Release history
CrossWatch releases
Sync media watch statuses across platforms
All releases
103 shown
Icons load locally for better privacy and the exporter no longer shows a duplicate dropdown.
Full changelog
CrossWatch v0.9.19
Just a small cleanup release.
Icons now load locally for better privacy and the exporter provider selector no longer shows a duplicate dropdown.
We are getting close to the v1.0.0 production thus stable release. From that point onward, production and development releases will be handled separately, so stable users can stay on reliable builds while development changes can continue without disturbing the production version.
🔧 Fixes & Improvements
- Improved: Material Symbols icons are now loaded locally instead of from Google Fonts, improving privacy and compatibility with restricted networks.
- Fixed: The exporter now shows only the intended icon-based provider selector instead of rendering a duplicate dropdown.
- Changed: Updated the version to
v0.9.19
- New Plex watcher route filter ignores Live TV & DVR playback
- Quick Add for manually sending watched history, watchlist entries, and ratings
Full changelog
CrossWatch v0.9.18
New Quick Add for desktop and mobile, manually send history, ratings and watchlist actions to one or more providers for titles watched outside your normal media server flow.
WIKI: https://wiki.crosswatch.app/crosswatch/navigation/quick-add
✨ Highlights
- Added: new Plex watcher route filter to ignore Live TV & DVR playback.
- Added: Quick Add for manually sending watched history, watchlist entries, and ratings to configured providers.
🔧 Fixes & Improvements
- Fixed: Jellyfin and Emby pair setups now correctly hide and disable Ratings where ratings sync is not supported.
- Fixed: Dashboard startup no longer waits on slow cold /api/status provider probes before loading the main widgets.
- Improved: /api/status now runs provider user-info lookups concurrently to reduce cold status latency.
- Improved: /api/state/wall now caches repeated identical responses until sync state, config, or wall filters change.
- Changed: Watchlist auto-remove now targets providers from enabled watchlist pairs instead of scanning all configured providers.
- For installations using Plex and/or MDBList, perform a cache clear (Clear everything or state and provider cache) after upgrading.
- Existing Plex/Jellyfin/Emby pairs must have Strict ID Matching enabled manually to retain expected behavior.
- Strict ID matching is now the default for new Plex, Jellyfin, and Emby provider pairings; existing pairs require manual enabling of Strict ID Matching.
Full changelog
CrossWatch v0.9.17
Strict ID matching is now the default for Plex, Jellyfin, and Emby, because title fallback causes too many false positives.
Existing pairs needs to be changed manually (but only if you have issues)
If you have Plex and/or MDBList in your pairs: Maintenance -> Clear everything (or state and provider cache)
✨ Highlights
- Refactored Sync Hub previews item/title spotlights are now delivered through the UI summary path instead of the raw sync output.
- Updated: Providers pair settings now use Strict ID matching as the new default standard for newly configured pairs**
- for existing pairs you need to change it in your pair - providers - Plex/Emby/Jellyfin and enable Strict ID Matching
🔧 Fixes & Improvements
- Fixed: One-way MDBList -> Plex ratings no longer apply mirror-style removals in non-mirror mode.
- Fixed: MDBList rating deletions are now detected more reliably when only journal activity changes.
- Fixed: Watchlist poster view could fail to render covers because of an undefined typeLabel error
- Fixed: Re-adding ratings after a delete no longer fails because sparse MDBList journal rows dropped needed metadata.
- Fixed: Plex history items can now be re-added after removal because stale local watched-cache state is cleared correctly.
- Fixed: upgrade warning reappearing after the first acknowledgement
- Maintenance -> Clear state and provider cache (or Clean everything) after provider changes.
- All providers, trackers, and media servers now use `x.x` versioning instead of `x.x.x`, starting from version `1.0`.
- Ignore dropped shows support for MDBList, Trakt, and SIMKL
- CW Tracker progress can be synced in/out like Plex, Emby, Jellyfin
- Improved Analyzer validates sync providers and orchestrator modules
Full changelog
CrossWatch v0.9.16
A lot of work in this version went into making sync behavior easier to trust in day-to-day use.
The goal was simple: make sync behavior more predictable, make summaries easier to trust and reduce false positives.
A big part of the providers (trackers/media servers) are refactored.
All providers, trackers, and media servers now use x.x versioning instead of x.x.x, starting from version 1.0.
As always when providers are changed. Maintenance -> Clear state and provider cache (or Clean everything)
✨ Highlights
- Ignore dropped shows support for MDBList, Trakt, and SIMKL, so your dropped titles can be excluded from sync behavior.
- CW Tracker progress support progress can now be synced into and out of the CrossWatch tracker just like Plex, Emby, and Jellyfin.
- Improved Analyzer is now more useful: as it validates sync providers and orchestrator modules.
🔧 Fixes & Improvements
- Fixed: Multiple edge cases where rating changes in two-way sync could be misread as adds or removals.
- Fixed: Re-rating items after deleting a rating could be blocked by stale pair tombstone behavior.
- Fixed: Recent sync summaries could show wrong counts because fallback stats could overwrite real zero-result runs.
- Fixed: Spotlight rows stay aligned with the actual applied sync results.
- Fixed: Apply events now carry richer spotlight data, improving reliability of the live sync UI.
- Fixed: Watermarks, shadow caches, and unresolved tracking are now handled more safely during capture/backup-style operations.
- Fixed: Progress fields are now preserved more reliably in persisted state, improving editor visibility and analyzer accuracy.
- Fixed: Editor loading was improved
- Improved: MDBList history syncing now handles rollups, episode removals, and journal-driven deletes much more reliably.
- Improved: SIMKL, Trakt, and MDBList large delete/apply operations now use safer provider-side chunking
- Improved: Cleanup tools now run in capture-style mode
- Improved: Compact/mobile handling is now smarter.
- Improved: Provider comparison logic was refactored to better match the way different services represent.
- Improved: Internal sync guardrails around tombstones, unresolved items, etc.
- Improved: Analyzer results are now more readable for end users, with clearer messages and better grouping.
- Removed old legacy watcher code, leftover UI pieces, and outdated migration paths.
- Added “Other browser sessions” summary and single “Log out other sessions” action in Security UI.
- Global defaults and per‑route control for watcher settings (global + route‑specific options).
- Watcher routes now open filters directly per route for easier setup.
- Improved active playback UI to support multiple streams better.
Full changelog
CrossWatch v0.9.15
Normally, I do about one release per week. But...
This one is an URGENT UPDATE and I strongly recommend everyone update to this image as soon as possible. Why? Because I broke it :-(
✨ Highlights
- Global defaults and per-route control: Watcher settings now support both global defaults and route-specific options.
- Simple setups stay easy while advanced setups get much more flexibility. https://github.com/cenodude/CrossWatch/issues/172
- For the plex ratings webhook you can now create a webhook per route. I think nobody will use it...but its there.
- For auto-remove on watchlist, same thing. You can set it globally or per route.
- Watcher routes refreshed: Filters and options now open directly per route, making watcher setup much easier to understand. https://github.com/cenodude/CrossWatch/issues/172
- Better active playback UI: The playing card and scheduler banner supports better multiple active streams. https://github.com/cenodude/CrossWatch/issues/173
- Trailer modal refreshed: provides a cleaner and better embedded viewing experience. https://github.com/cenodude/CrossWatch/issues/182
🔧 Fixes & Improvements
- Removed: Old legacy watcher code, leftover UI pieces, and outdated migration paths. https://github.com/cenodude/CrossWatch/issues/169
- Fixed: MDBList watchlist items are now classified more accurately. https://github.com/cenodude/CrossWatch/issues/177
- Fixed: Watchlist trailer playback now opens correctly again from the watchlist detail card. https://github.com/cenodude/CrossWatch/issues/182
- Fixed: Route filters now work correctly for Plex, Jellyfin, and Emby, including usernames, user IDs, and server UUIDs. https://github.com/cenodude/CrossWatch/issues/168
- Fixed: Watcher output tab showed only Plex and traks logs, thats fixed now and includes all watcher providers https://github.com/cenodude/CrossWatch/issues/170
- Fixed: Settings no longer spam repeated background config requests when you are not actively setting up a provider. https://github.com/cenodude/CrossWatch/issues/176
- Fixed: Watcher logs no longer spam the same filtered-session message over and over during blocked playback. https://github.com/cenodude/CrossWatch/issues/179
- Fixed: Unified watchlist items are now merged more reliably when different providers store the same title under different IDs. https://github.com/cenodude/CrossWatch/issues/177
- Added: Per-route watcher options such as route-specific auto-remove, plus custom Plex ratings webhooks. https://github.com/cenodude/CrossWatch/issues/172
- Added: New lightweight health check endpoints: /api/health and /healthz for your docker healthcheck https://github.com/cenodude/CrossWatch/issues/175
- Improved: Plex history and ratings indexing now use parallel workers. In testing, about a 34% speed improvement https://github.com/cenodude/CrossWatch/issues/181
- Improved: Jellyfin and Emby watcher behavior is now much closer to Plex for seek, progress, and stop handling. https://github.com/cenodude/CrossWatch/issues/172
- Improved: Watcher and sink logging is now more consistent and easier to follow. https://github.com/cenodude/CrossWatch/issues/172
- Improved: Watchlist delete actions now resolve correctly across providers with merged IDs. https://github.com/cenodude/CrossWatch/issues/177
- Improved: Watchlist metadata is now batched per visible set instead of sending one metadata request per item. https://github.com/cenodude/CrossWatch/issues/174
- Improved: Watchlist row hydration now only requests the metadata needed for the list view. https://github.com/cenodude/CrossWatch/issues/174
- Improved: Metadata cache reuse on the watchlist page is more effective and reducing unnecessary TMDb traffic. https://github.com/cenodude/CrossWatch/issues/174
- Improved: Main-page watchlist preview now loads faster by rendering sooner. https://github.com/cenodude/CrossWatch/issues/182
- Improved: Watchlist and playing-card metadata reuse is now more effective. https://github.com/cenodude/CrossWatch/issues/182
🔐 Security
- UI and Security: In Security UI added “Other browser sessions” summary with a single “Log out other sessions” action. https://github.com/cenodude/CrossWatch/issues/183
- Removed the old watcher bridge; migrate from legacy watcher setup (<0.9) to watcher routes
- Perform a hard browser refresh (Ctrl+Shift+R or Ctrl+F5) after upgrade
- Authentication is now mandatory for all endpoints.
- Username masking in watcher/sink and webhook logs – only first two letters are shown
- Plex SSO support allowing login via linked Plex account with local admin fallback
- Advanced Scheduling with event‑triggered actions and a new Event Triggers panel
Full changelog
CrossWatch v0.9.14
Authentication is now mandatory. As it is the only reliable way to properly protect the endpoints.
To make things a bit easier, I added extended session caching and also Plex SSO support.
In the background, I am also working on a major overhaul of the orchestrator and providers, with more improvements coming in the next releases. The goal for the orchestrator/provider overhaul is better matches and less API requests.
After the upgrade to a hard browser refresh: Ctrl+Shift+R or Ctrl+F5
✨ Highlights
- Authentication:
- New login screen: cleaner layout, improved session options.
- Plex SSO: CrossWatch can now use a linked Plex account for sign-in, while still keeping the normal local admin login as fallback.
- Settings refresh: Settings overview has now a more progress-step approach. Making it easier for new users...well, i hope.
- Advanced Scheduling: can now trigger actions by events (watcher/webhook activity) and capture scheduling
- Scheduling UX refresh: Standard Scheduling is now more flexible with more recurrence options.
- both Standard and Advanced Scheduling have a clearer setup experience.
- Connection Setup: the Configure Connection modal was refreshed.
🔧 Fixes & Improvements
- New: optional Sign in with Plex button on the login page for linked Plex admins.
- New: Security settings now allow linking or unlinking a Plex account for CrossWatch sign-in.
- Improved: authentication now reuses existing CrossWatch session cache and middleware protection.
- Improved: login and security settings received additional UI polish and clearer auth/session messaging.
- Improved: Standard Scheduling now supports Every hour, Every N hours, Daily at, and Custom interval modes. https://github.com/cenodude/CrossWatch/issues/165
- Improved: Standard Scheduling now uses a more guided wizard-style setup https://github.com/cenodude/CrossWatch/issues/165
- Improved: both Standard and Advanced Scheduling now include a clearer Current plan summary. https://github.com/cenodude/CrossWatch/issues/165
- Fixed: Sync Output no longer replays duplicate scheduler log lines after reconnecting the live log stream.
- Fixed: some frontend views did not correctly use cached TMDb metadata https://github.com/cenodude/CrossWatch/issues/143
- Fixed: History sync could miss watched history when rating a new movie auto-moved it to completed https://github.com/cenodude/CrossWatch/issues/153
- Fixed: editor watchlist entry could duplicate on sync due to TMDb/IMDb key mismatch https://github.com/cenodude/CrossWatch/issues/147
- Fixed: Sync Details output now refreshes reliably across consecutive syncs https://github.com/cenodude/CrossWatch/issues/154
- Fixed: disabling the CrossWatch tracker now properly hides CrossWatch from Insights, Watchlist, Editor, and Snapshots https://github.com/cenodude/CrossWatch/issues/160
- Removed: the old watcher bridge is removed; if you're still using the legacy watcher setup (<0.9), you need to move to watcher routes.
- Change: Captures now support bundles/full captures for diff compare https://github.com/cenodude/CrossWatch/issues/144
- Change: Captures can be scheduled directly in advanced scheduler or add as queue in Captures https://github.com/cenodude/CrossWatch/issues/89
- Change: added a separate Event Triggers panel next to the existing Time Plan in Advanced Scheduling https://github.com/cenodude/CrossWatch/issues/148
- Change: settings and connection setup now include more helper icons and tooltips https://github.com/cenodude/CrossWatch/issues/158
🔐 Security hardening https://github.com/cenodude/CrossWatch/issues/146
- username masking: for all watcher/sink and webhook logs. You now see only the first two letters of a username.
📚 WIKI updates:
- Scheduler: https://wiki.crosswatch.app/crosswatch/scheduling
- Captures: https://wiki.crosswatch.app/crosswatch/tools/captures
- Plex SSO: https://wiki.crosswatch.app/crosswatch/navigation/ui-settings/security/plex-sso
- Config files are now encrypted; downgrading from v0.9.13 is unsupported.
- Sensitive values in config.json are stored encrypted using a local master key (reduces accidental leakage)
- UI refresh with cleaner, modern status presentation across main, analyzer, exporter, syncbar, Watchlist, Captures, Editor, and Settings
- Added `Copy` button to Sync output toolbar for quick log copying
Full changelog
CrossWatch v0.9.13
Important, after your upgrade to v0.9.13 you cant downgrade. This version now includes encrypted config file, and is not comptabile with older versions. Hope you like the improved interface. The orchestrator and adapters were not changed, so there is no need to delete your cache.
✨ Highlights
- UI Refresh: Updated with a cleaner, more modern and improved status presentation for a fresher overall look (i hope) https://github.com/cenodude/CrossWatch/issues/137
- updated: UI changes for main, analyzer, exporter, syncbar, Watchlist, Captures, Editor, Settings
- Refactor: Cleaned up, updated, and removed unnecessary parts for significantly better performance. https://github.com/cenodude/CrossWatch/issues/134
🔧 Fixes & Improvements
- Fixed: Scheduler thread is being started even when scheduling is fully disabled. https://github.com/cenodude/CrossWatch/issues/133
- Fixed: Setup wizard now opens correctly again after using Reset all to default https://github.com/cenodude/CrossWatch/issues/136
- Fixed: Browser accessibility/compliance warnings caused by unbound labels. https://github.com/cenodude/CrossWatch/issues/135
- Fixed: Increased modal slightly and fixed status badge clipping in the header area.
- Fixed: Cut down repeated scheduler start/stop messages during save and refresh. https://github.com/cenodude/CrossWatch/issues/132
- Fixed: Insight Settings Filtering:** The provider list in Insight Settings now shows only providers that are configured.
- Change: Added a
Copybutton to the Sync output toolbar so you can quickly copy the activeSyncorWatcherlog. https://github.com/cenodude/CrossWatch/issues/131 - Change: Watchlist, swapped the numeric overview for Coverage Pulse.
🔐 Security Enhancements https://github.com/cenodude/CrossWatch/issues/123
- Encrypted secrets: Sensitive values are now stored encrypted in
config.jsonwhen settings are saved.- CW uses a simple local master key file to decrypt them when needed.
- It will reduce accidental leakage but it does not protect against a compromised host.
- WIKI: https://wiki.crosswatch.app/crosswatch/configuration-config-json/config-encryption
- Clear existing cache before upgrading (Settings → Maintenance → Clear Everything) for improvements to take effect.
- After updating, copy and paste the new webhook URLs into each media server configuration.
- If using reverse proxies, configure the Trusted reverse proxies setting in Settings → Security.
- All Webhook endpoints now require a unique URL/ID token; existing webhook URLs are invalidated and must be replaced with the new ones after upgrade.
- Hardened TMDb artwork caching to block path traversal / unintended file overwrite.
- Webhook endpoints now require a unique URL token for authentication.
- Authentication fails closed if config.json cannot be loaded/parsed correctly.
- Experimental Progress feature: sync resume positions between Plex, Emby, and Jellyfin (configurable per‑pair, supports one‑way or two‑way).
Full changelog
CrossWatch v0.9.12
Another huge update as i've continuing the work started in 0.9.11, where we moved from IMDb-first to TMDB-first.
I’ve made a bunch of optimizations and tightened up the orchestrator integration, so your sync results should be more reliable.
There’s also a new experimental feature called Progress, which lets you sync resume positions between media servers.
And last, but definitely not least, security has been improved.
IMPORTANT - what you absolutely need to do:
- All Webhooks are now protected with a unique URL/ID token. After updating, every (webhook)user must copy and paste the new webhook URL into their media server.
- As always, clear your existing cache first, it’s the smartest thing you can do. In Settings - Maintenance - Maintenance tools and then Clear Everything
- If you don’t clear your existing cache, most improvements won’t be applied. That makes all my work a complete waste....so sad..
✨ Highlights
- Progress (Experimental): Sync resume position between Plex, Emby, and Jellyfin https://github.com/cenodude/CrossWatch/issues/119
- Configurable per pair (source from/to target), supports one-way and two-way sync
- WIKI: https://wiki.crosswatch.app/crosswatch/configure-pairs/features/progress
🔧 Fixes & Improvements
-
History Sync Reliability: https://github.com/cenodude/CrossWatch/issues/117
- Fixed a state persistence issue that could cause history statistics to shrink after a subsequent sync run.
- CW now preserves watched timestamps/metadata when a provider returns sparse history.
- Improved ID reconciliation to prevent duplicate history entries when providers disagree on IDs:
- Uses TMDb first, then falls back to IMDb, then TVDb (in that order) to match the same title across systems.
- Two-way sync: improved safeguards so ID drift doesn’t trigger false adds/removes or inflated counts.
-
Plex Instances / Profiles: Fixed an issue where Plex per-instance library whitelists)were not being saved https://github.com/cenodude/CrossWatch/issues/126
-
Plex Instances / Profiles: Fixed an issue where an extra PLEX-P01 could appear in settings. https://github.com/cenodude/CrossWatch/issues/129
-
Upgrade Migration: The Migrate action in the upgrade warning modal now performs a real migration for required settings. https://github.com/cenodude/CrossWatch/issues/130
-
History Sync Performance (Jellyfin / Emby / Trakt): Much faster history indexing....more speeeeeeeeeeeed https://github.com/cenodude/CrossWatch/issues/125
-
Provider Rate Limiting (SIMKL / Trakt / MDBList): Added configurable request throttling to respect upstream API limits. https://github.com/cenodude/CrossWatch/issues/128
-
Security Enhancements: https://github.com/cenodude/CrossWatch/issues/123
- Authentication now fails closed if `config.json exists but can’t be loaded/parsed correctly.
- Hardened TMDb artwork caching to block path traversal / unintended file overwrite.
- Webhook endpoints are now protected via a unique URL token generated by CW:
/webhook/plextrakt?uniqueID/webhook/jellyfintrakt?uniqueID/webhook/embytrakt?uniqueID/webhook/plexwatcher?uniqueID
- Added Trusted reverse proxies setting in Settings - Security
- Use this only if you run CW behind reversed proxies. This will improves secure cookies and rate limiting accuracy.
- UI logs now redact common secrets (tokens/keys) to reduce leakage.
- TLS certificate download endpoint now only serves valid X.509 cert files
- Improved error handling to avoid leaking internal details via API responses.
- Stronger path validation to prevent unintended directory access via file listing.
- After upgrade, run **Migrate** which will clear existing state and pause the scheduler
- Re‑enable sync pairs one at a time post‑migration to allow gradual state rebuild
- Do not configure tracker‑to‑media‑server pairs until further testing is complete
- ID lookup order changed to TMDb → IMDb → TVDb (replaces previous split handling)
- Upgrade triggers wiping of current state and cache, temporarily stopping the scheduler
Full changelog
CrossWatch v0.9.11
Read this. Or cry later. Your choice.
BREAKING UPDATE: ID priority is now TMDb-first
Classic small change, huge impact.
This affects every sync pair. The old split (IMDb for UI/state, TMDb for sync) became too fragile and kept causing avoidable bugs.
I've changing it now so we can actually reach a stable release someday.
CrossWatch now prefers IDs in this order: TMDb → IMDb → TVDb → (everything else).
Why this matters
- Better matching across providers
- Fewer duplicates and unresolved items
Migration behavior (important)
When you upgrade and click Migrate, we will:
- Wipe your current state and cache
- Temporarily stop your scheduler
This is intentional. It prevents duplicate entries from being pushed to your trackers.
After migration
- Re-enable one pair at a time and let it rebuild your state gradually
- If you have captures; recreate them.
- At the moment DONT do any tracker to media server pairs.
Testing
This also means that large parts of CrossWatch need to be re-tested. I’ll phase this in, because I’m a one-person operation.
- Webhooks / Watcher: Tested
- Sync pairs - Plex to trackers: Tested
- Sync pairs - tracker from/to tracker: Tested
Next up: testing Emby/Jellyfin (and friends). I’m not expecting major issues, but please be careful. Plex has already been updated as a delta provider; we still need to apply the same change for Emby/Jellyfin. Until that’s done, the Emby/Jellyfin results won’t reflect any improvements yet.
🔧 Fixes & Improvements
- CrossWatch: Reorder ID keys for consistency across various modules (TMDB first) https://github.com/cenodude/CrossWatch/issues/117
- Orchestrator: Many improvements for better sync results.
- Plex Sync (History): Fixed an issue where Plex history could drop to
0on the second sync - Plex Sync (History): Improved state handling so Plex history is treated as incremental (“delta”)
- Plex Sync (History): Reduced false weird counters in Insights caused by incremental snapshots being stored as full snapshots.
- Plex Sync (History): Improved shows/episode enrichment.
- Trakt Sync (History): Fixed a loop where history sync could report
+1 addedon every run even when nothing new was added. - Trakt Sync (History): Improved episode matching
- Trakt Sync (History): Corrected unresolved/blocked handling so repeated failures are properly blocked
- MDBList adapter updated to v4.1.0 with improved API compatibility
- SIMKL adapter updated to v4.1.0 adding anime scrobble payload support and season sync fixes
- Trakt adapter updated to v4.4.0 fixing watchlist syncing for seasons/episodes and pause‑rejection logging
Full changelog
CrossWatch v0.9.10
🔧 Fixes & Improvements
- Scrobble: Suppressed
user=Noneplayback alerts to reduce filter-log noise when no one is actively watching. - Scrobble: Fixed non-default scrobble watchers missing playback events when Plex alert payloads omit the account/user field.
- Scrobble: Added a debug log entry before dropping unresolved-user alerts to make it clearer why an event was ignored.
- Scrobble: Improved support for Plex shared-server tokens by using the configured profile username for that watcher.
- Scrobble UI: Fixed route filter settings leaking into the default profile due to cached provider presets while editing routes.
- Captures: Fixed history-restore gaps when two entries share the same watch timestamp.
- Captures: Fixed an edge case where items can return multiple distinct items with the same IMDb ID.
- Sync Engine: Improved bulk sync completion performance by batching internal blackbox/flap bookkeeping instead of updating it item-by-item.
- Fixed an issue where large sync runs, especially history imports, could appear to stall after the write phase while CrossWatch was still processing internal retry/unresolved tracking.
- Reduced post-sync overhead for large add/remove operations so runs can finish and report completion more reliably.
- Sync Engine: Improved sync result reporting for large one-way runs.
- Added clearer accounting for provider-confirmed adds versus internally deduplicated items.
- Improved skipped-item reporting so inferred remainder skips are tracked more transparently during bulk syncs.
- Added better visibility into duplicate canonical-key collapse during apply/reporting, which helps explain mismatches between provider-reported adds and final run totals.
- MDBList: Updated the MDBList adapter to v4.1.0.
- Improved sync compatibility with the current MDBList API blueprint across history, ratings, watchlist, and scrobble flows.
- Fixed watched-history sync handling for show-level and season-level updates/removals.
- Improved ratings sync support for additional MDBList-supported IDs, including Trakt, MDBList, and Kitsu where applicable.
- Hardened watchlist parsing for unified responses and aligned internal health checks/activity tracking with MDBList sync behavior.
- SIMKL: Updated the SIMKL adapter to v4.1.0.
- Improved compatibility with the current SIMKL API blueprint across history, ratings, watchlist, and scrobble flows.
- Fixed anime scrobble handling by sending the correct SIMKL payload shape and supporting additional anime IDs where available.
- Improved history and ratings sync matching by preserving a broader set of SIMKL-supported IDs.
- Fixed an anime ratings sync issue where SIMKL anime library data could be parsed incorrectly, causing weaker item matching.
- Hardened Plan to Watch sync by correctly accepting successful SIMKL removals even when the API returns an empty response body.
- Fixed history season sync handling by sending season entries using SIMKL's documented season payload shape instead of treating them like plain show-level writes.
- Improved SIMKL history write accounting so successful season-level additions are counted correctly during bulk imports.
- Trakt: Updated the Trakt adapter to v4.4.0.
- Improved compatibility with the current Trakt API blueprint across history, ratings, watchlist, and scrobble flows.
- Fixed watched-history sync handling for show-level and season-level updates/removals, and improved support for removing entries by Trakt history ID.
- Improved watchlist sync support for movies, shows, seasons, and episodes to better match Trakt's supported payloads.
- Fixed scrobble behavior that could create multiple watched dates when stopping near the end and finishing later (configurable via
stop_pause_threshold). - Improved scrobble logging by downgrading Trakt
422pause rejections near the scrobble cutoff to WARN (no longer treated as hard errors). - Hardened scrobble handling for duplicate/recent playback conflicts to better align with Trakt responses.
- Shared Plex server support (non‑owner servers)
- Separate tokens for Plex cloud account and PMS access
- Fallback‑GUID option prevents history sync entry loss
Full changelog
CrossWatch v0.9.9 (quick-fix)
Because of filtering issues affecting Plex users. I’m releasing this quick fix.
This patch is focused on improving user detection and filtering behavior, which should reduce incorrect matches and missed events.
It removes the PMS owner fallback and relies more on actual session/user data, which should give more consistent results.
The main or real issue is that Plex is very inconsistent when it comes to providing the actual usernames.
This is a quick fix(hotfix). It hasn’t been thoroughly tested yet, so treat it as an improvement release rather than a guaranteed final fix.
That said, it should deliver better results than the current (0.9.8) version regaring watcher and filtering for Plex.
🔧 Fixes & Improvements
- Plex: Fixed misidentificationstreams as the server owner, which affect route filters.
CrossWatch v0.9.8
Important (Plex users)
CrossWatch now supports shared Plex servers (servers you don’t own - no PMS owner) thanks for the idea and support @mesitisg
This required major changes to Plex authentication and sync adapters.
Recommended action: Recreate your Plex authentication configs (delete and re-add)
- Disable Watcher first before recreating Plex auth
- You can keep your pairs and watcher config.
- Dont forget to set your whitelists and double check your Plex settings.
✨ Highlights
- Plex: Shared Plex server support is now supported (sync and watcher)
🔧 Fixes & Improvements
- Plex: Keeps separate tokens for Plex account (cloud) and Plex server (PMS) access, so PMS features use the correct token.
- Plex: History and ratings sync now use the PMS-scoped token, fixing shared-server authorization issues.
- Plex: Manual Mark as Watched/Unwatched actions in Plex are now tracked more reliably for history sync and use a separate cache.
- Plex: Fallback-GUID option. History sync no longer drops entries. https://github.com/cenodude/CrossWatch/issues/111
- Scrobble: With multiple scrobble routes, CW now logs a single summary line (wired providers: X | wired sinks: Y).
- Scrobble: Newly created provider profiles/instances now appear immediately in Watcher route dropdowns.
- Scrobble: Fixed route filter UI state leaking between routes. Opening Filters now loads the correct filters for the selected route.
- Scrobble: Removed the Live panel/toggle from the Watcher screen. It was confusing for most users.
- Tautulli: Fixed auth UI where the auth buttons were not visible. (Issue #112)
- Captures: CW now uses a dedicated Capture Mode when creating captures, ignoring cache and watermarks for consistancy. https://github.com/cenodude/CrossWatch/issues/110
- Disable Watcher before recreating Plex auth; keep pairs and watcher config.
- Recreate Plex authentication configs by deleting and re‑adding them.
- Set whitelists and double‑check Plex settings after migration.
- Recreation of Plex authentication configs required due to major changes in Plex authentication and sync adapters.
- Support for shared Plex servers (sync and watcher).
Full changelog
CrossWatch v0.9.8
Important (Plex users)
CrossWatch now supports shared Plex servers (servers you don’t own - no PMS owner) thanks for the idea and support @mesitisg
This required major changes to Plex authentication and sync adapters.
Recommended action: Recreate your Plex authentication configs (delete and re-add)
- Disable Watcher first before recreating Plex auth
- You can keep your pairs and watcher config.
- Dont forget to set your whitelists and double check your Plex settings.
✨ Highlights
- Plex: Shared Plex server support is now supported (sync and watcher)
🔧 Fixes & Improvements
- Plex: Keeps separate tokens for Plex account (cloud) and Plex server (PMS) access, so PMS features use the correct token.
- Plex: History and ratings sync now use the PMS-scoped token, fixing shared-server authorization issues.
- Plex: Manual Mark as Watched/Unwatched actions in Plex are now tracked more reliably for history sync and use a separate cache.
- Plex: Fallback-GUID option. History sync no longer drops entries. https://github.com/cenodude/CrossWatch/issues/111
- Scrobble: With multiple scrobble routes, CW now logs a single summary line (wired providers: X | wired sinks: Y).
- Scrobble: Newly created provider profiles/instances now appear immediately in Watcher route dropdowns.
- Scrobble: Fixed route filter UI state leaking between routes. Opening Filters now loads the correct filters for the selected route.
- Scrobble: Removed the Live panel/toggle from the Watcher screen. It was confusing for most users.
- Tautulli: Fixed auth UI where the auth buttons were not visible. (Issue #112)
- Captures: CW now uses a dedicated Capture Mode when creating captures, ignoring cache and watermarks for consistancy. https://github.com/cenodude/CrossWatch/issues/110
- Trakt adapter now rounds `watched_at` timestamps to minute precision, breaking existing history pairs; users must recreate the pair or run maintenance tools.
Full changelog
CrossWatch v0.9.7
This release streamlines and improves scheduling for a more reliable overall experience.
✨ Highlights
- Scheduler status: The banner and Setting Insight now reflect Standard and Advanced scheduling modes.
🔧 Fixes & Improvements
- Scheduler: guardrails: Switching to Advanced automatically turns Standard off (and vice versa) to prevent conflicting schedules.
- Scheduler: logs: Added scheduler logs (start / next run / trigger / success / failure) so scheduled runs aren’t silent.
- Scheduler: next-run handling: Disabling scheduling no longer shows a far-future placeholder.
- Advanced scheduler: Advanced jobs now correctly catch up if a job time has already passed.
- Advanced scheduler: The banner now makes it obvious when the next run is today vs tomorrow/another day.
- Settings Insight: Insight refreshes far less when the Settings page isn’t open, improving overall UI performance.
- Settings Insight: Prevents re-rendering when nothing changed, reducing repeated icon reloads.
Previous change v0.9.6 below:
CrossWatch v0.9.6
Big changes: the Plex adapter (history and ratings) was refactored for better accuracy and much faster history syncs.
First run may still be slow, but follow-up runs should be way faster.
For users still on v0.8.x, now’s the perfect time to upgrade to v0.9.6.
⚠️ Warning possible breaking update for Trakt History pairs
Trakt is rolling out a change that rounds watched_at to minute precision
I've changed the Trakt adapter following that same principle now.
If you have a pair with Trakt using History then either recreate the pair or even better:
Go to maintenance tools to clean everything. Ref: https://wiki.crosswatch.app/crosswatch/faq
✨ Highlights
- Snapshots - Captures: The UI now labels “Snapshots” as Captures.
- Captures Compare (Advanced): Side-by-side A/B diff viewer. Select two Captures, then click Advanced. Ref: https://wiki.crosswatch.app/crosswatch/tools/captures/capture-compare-advanced
🔧 Fixes & Improvements
- Trakt: minute precision: Changed the Trakt adapter to follow-up the new minute precision approach.
- Plex: Home token reliability: History writes now use the active Plex session token (prevents “sometimes only season 1” / random unresolved writes when Plex Home switching is involved).
- Plex: Strict IDs-only matching: History sync is now fixed and can run in strict ID mode using Plex GUIDs (TMDB/IMDb/TVDB) without title/search fallbacks. This reduces mismatches and makes “IDs-only” actually work.
- Plex: history capture: Plex history capture is now incremental (watermark and correct
mindateusage) instead of re-scanning the entire server history every run. - Plex: Persistent GUID index: Uses a per-pair, on-disk GUID→ratingKey index to speed up strict matching.
- Plex: ratings strict matching improved: Episode/season ratings resolution now also uses show IDs (TMDB/IMDb/TVDB) when matching in Plex, improving accuracy and reducing “unresolved” ratings in strict ID mode.
- Editor: timestamps: “Watched At” display/editing now matches the UI. Manual edits are interpreted in local time and stored consistently (prevents timezone shifts).
- Captures - Compare: Compare is now limited to same provider and same feature to prevent misleading diffs. Ref: https://github.com/cenodude/CrossWatch/issues/97
- Captures - Compare: Smarter diffing (including timestamp normalization) to avoid false “updates” caused by tiny time differences. Ref: https://github.com/cenodude/CrossWatch/issues/97
- Plex: history timestamps: Fixed a potential timezone offset issue by reading Plex history using Plex’s native epoch format for consistent results. Ref: https://github.com/cenodude/CrossWatch/issues/103
- Pair-config - One-Way Remove mode UI toggle: Added a new switch in pair-config under Allow mass delete to control one-way deletion behavior:
- Enabled (default): Deletions are based on source matches — items are only deleted when a match exists between source and destination.
- Disabled: Mirror mode (
mirror) - always follows source (destructive; use with care). - NB: The logics was already available in v0.9.5, i only added the UI toggle.
- Ref: https://wiki.crosswatch.app/crosswatch/configure-pairs/global-settings
- For existing Trakt‑History pairs, run the maintenance tool to clean data or recreate the pair after upgrading to v0.9.6.
- Plex history sync defaults to strict ID mode; ensure GUID mappings are present for accurate matching.
- Trakt adapter rounds `watched_at` timestamps to minute precision; existing Trakt‑History pairs must be recreated or cleaned via maintenance tools.
- Plex adapter refactored for faster, more accurate history syncs (incremental watermark, persistent GUID index).
- Captures renamed to **Captures** in UI with new **Advanced Compare** side‑by‑side diff viewer.
- Editor timestamps now display/edit "Watched At" consistently using local time.
Full changelog
CrossWatch v0.9.6
Big changes: the Plex adapter (history and ratings) was refactored for better accuracy and much faster history syncs.
First run may still be slow, but follow-up runs should be way faster.
For users still on v0.8.x, now’s the perfect time to upgrade to v0.9.6.
⚠️ Warning possible breaking update for Trakt History pairs
Trakt is rolling out a change that rounds watched_at to minute precision
I've changed the Trakt adapter following that same principle now.
If you have a pair with Trakt using History then either recreate the pair or even better:
Go to maintenance tools to clean everything. Ref: https://wiki.crosswatch.app/crosswatch/faq
✨ Highlights
- Snapshots - Captures: The UI now labels “Snapshots” as Captures.
- Captures Compare (Advanced): Side-by-side A/B diff viewer. Select two Captures, then click Advanced. Ref: https://wiki.crosswatch.app/crosswatch/tools/captures/capture-compare-advanced
🔧 Fixes & Improvements
- Trakt: minute precision: Changed the Trakt adapter to follow-up the new minute precision approach.
- Plex: Home token reliability: History writes now use the active Plex session token (prevents “sometimes only season 1” / random unresolved writes when Plex Home switching is involved).
- Plex: Strict IDs-only matching: History sync is now fixed and can run in strict ID mode using Plex GUIDs (TMDB/IMDb/TVDB) without title/search fallbacks. This reduces mismatches and makes “IDs-only” actually work.
- Plex: history capture: Plex history capture is now incremental (watermark and correct
mindateusage) instead of re-scanning the entire server history every run. - Plex: Persistent GUID index: Uses a per-pair, on-disk GUID→ratingKey index to speed up strict matching.
- Plex: ratings strict matching improved: Episode/season ratings resolution now also uses show IDs (TMDB/IMDb/TVDB) when matching in Plex, improving accuracy and reducing “unresolved” ratings in strict ID mode.
- Editor: timestamps: “Watched At” display/editing now matches the UI. Manual edits are interpreted in local time and stored consistently (prevents timezone shifts).
- Captures - Compare: Compare is now limited to same provider and same feature to prevent misleading diffs. Ref: https://github.com/cenodude/CrossWatch/issues/97
- Captures - Compare: Smarter diffing (including timestamp normalization) to avoid false “updates” caused by tiny time differences. Ref: https://github.com/cenodude/CrossWatch/issues/97
- Plex: history timestamps: Fixed a potential timezone offset issue by reading Plex history using Plex’s native epoch format for consistent results. Ref: https://github.com/cenodude/CrossWatch/issues/103
- Pair-config - One-Way Remove mode UI toggle: Added a new switch in pair-config under Allow mass delete to control one-way deletion behavior:
- Enabled (default): Deletions are based on source matches — items are only deleted when a match exists between source and destination.
- Disabled: Mirror mode (
mirror) - always follows source (destructive; use with care). - NB: The logics was already available in v0.9.5, i only added the UI toggle.
- Ref: https://wiki.crosswatch.app/crosswatch/configure-pairs/global-settings
- Clear browser cache after upgrading.
- Watcher Routes model is experimental; keep progress step at the default 25 % (validate in advanced) to avoid excessive API calls that could be throttled by trackers.
- Provider Profiles / Instances – multiple profiles per provider (e.g., Plex “Default” and “Kids”) enabling sync hub for family or friends
- Watcher Routes model – configure any media server(s) with any tracker(s) to run together; legacy configs migrate to routes mode with default profile applied
- Insights Settings UI – new modal to include/exclude Features and Provider Profiles
Full changelog
CrossWatch v0.9.5
There was an issue with the Trakt provider when using multiple profiles: additional profiles incorrectly reused the default profile’s client_id.
Most users won’t notice this (because most don’t run multiple Trakt profiles), but if you do: delete all extra Trakt profiles (keep the default), then recreate them.
Another important change: the default delete behavior for one-way syncs has been updated. Previously, one-way deletes acted like “mirror mode” by default.
If you intentionally want the old (destructive) mirroring behavior back, set this in your config.json:
sync.one_way_remove_mode = "mirror"
✨ Highlights
- Watchlist list view improvements: Posters no longer collide with sync icons; the layout is cleaner and easier to scan.
- Snapshots comparison: Pick two snapshots and see what changed - Added, Deleted, and Updated (with old/new values).
🔧 Fixes & Improvements
- Synchronization Providers / Pairs: Fixed the pairs list getting cut off when you have many pairs; it now becomes scrollable after ~5 pairs.
- Providers (multi-profile visibility): Provider status now always reflects your default profile, even if other profiles exist.
- Providers (tooltip improvements): Hovering a provider now shows which profiles/instances are configured and which ones are actually used by your sync pairs.
- Watchlist: Provider icons no longer “jump” left/right per item. Each provider now keeps a fixed slot, making it easier to spot what isn’t synced.
- Watchlist (customizable columns): You can now show/hide columns like Poster, Genre, etc., to build your preferred view.
- MDBList (Watchlist IDs): Watchlist items from MDBList now correctly store TMDb IDs (instead of losing them), improving matching and reducing duplicates.
- Providers (ID preference): Provider ID matching now prefers TMDb before IMDb for improved consistency across integrations. (Orchestrator behavior is unchanged.)
- Trakt (per-pair Collection sync): Add to Trakt Collection is now configured per Trakt pair instead of globally.
- Trakt (Movies/Shows selection): When enabled, you can choose whether Collection updates apply to Movies and/or Shows (default: Movies).
- Trakt (multi-profile auth): Fixed Trakt profiles not storing their own Client ID and Client Secret correctly.
- Trakt (renew all profiles): Token refresh/renew now applies to all Trakt profiles, not only the default one.
- One-way sync (safe deletes): Fixed one-way pairs with Delete enabled incorrectly behaving like mirror mode on subsequent runs, causing unintended mass deletions on the target. Deletes now only propagate items actually deleted on the source.
BELOW the v0.9.4 release notes:
CrossWatch v0.9.4
🔧 Fixes & Improvements
- Watcher Scrobble no longer defaults to Trakt when no sink is configured.
- Watcher If no scrobble sink is set, watching still works, we just don’t scrobble anywhere.
- Watchlist (Internal Tracker) Covers/posters now show up again in both Watchlist and Watchlist Preview
BELOW the v0.9.3 release notes:
CrossWatch v0.9.3
🔧 Fixes & Improvements
- Plex Auth / Profiles: Fixed profile settings leaking into the default profile. Profile values now stay isolated and update immediately. https://github.com/cenodude/CrossWatch/issues/80
- Plex Home Switching: Improved Home user switching logic (correctly distinguishes Home user ID vs Plex account ID) for more reliable profile/session behavior. https://github.com/cenodude/CrossWatch/issues/81
- Plex Module Cleanup: Refactored and centralized Plex sync code (shared helpers moved into
_common, removed duplication/unused code). - Maintenance: “Clear provider cache” and “Clean everything” now preserve
/config/.cw_state/id/(Plex device and auth identifiers stay intact). - Maintenance: Added “Reset all to default” Wipes local state/caches/reports/TLS, backs up
config.jsonwith a timestamp, keeps snapshots, then restarts CrossWatch.
BELOW the v0.9.2 release notes:
CrossWatch v0.9.2
Updated Now Playing card and banner to properly handle multiple streams (Watcher Routes mode).
If anything looks off after updating: Settings → Maintenance → Reset Currently Playing.
You can also run sinlgle pairs now from the main Synchronize button..
✨ Highlights
- Split “Synchronize” button (new)
- Click Synchronize to run everything (as before).
- Click the ▾ to run Sync all or run a single enabled pair directly.
🔧 Fixes & Improvements
- Scrobble Watcher: Fixed an issue where resume after pause could be missed until the next progress milestone.
- Playing card (Routes mode): Now supports multiple simultaneous streams (such as Plex and Emby to same sink)
- Playing card: Fixed the Now playing time ticker.. it now shows the time played
BELOW the v0.9.1 release notes:
CrossWatch v0.9.1
As always: do a hard refresh (CTRL+F5) - or better, clear your browser cache.
The number of times caching causes ghost bugs is basically infinite. So tripple please...do it...
🔧 Fixes & Improvements
- Emby/Jellyfin “Pick User”: Fixed a front-end bind issue where the button could do nothing.
- Strict ID matching (per pair): Optional per-pair setting to match IDs only (disables title/year fallback) for Plex/Emby/Jellyfin.
- Plex Home user history: History sync now writes to the selected Home user, with a safety guard to skip writes if scope switching fails.
- Plex Watcher - Fetch Server UUID: Fixed No server UUID by using the correct UUID endpoint.
- Insights UI counters: Fixed tab counters not updating reliably when switching features.
BELOW the v0.9.0 release notes:
CrossWatch v0.9.0 (experimental)
v0.9.0 brings a new Profile/Instance system and the new Watcher Routes model.
It’s marked experimental because profiles multiply the possible setups far beyond what older CrossWatch builds had to handle.
If your current version works and are happy: you can just wait a few versions before it's stable again..
But if you want to upgrade to test it and help the community shake out bugs, I’ll gladly take it.
Expect rough edges while I stabilize the new foundation...Look it is what it is....
If I had to sum this release up in one sentence: you can now run CrossWatch as a multi-profile sync hub for multiple friends/family and their services, even using their tracker APIs.
IMPORTANT and WARNINGS
- Clear your browser cache for this release. i had some issues with it.. cleaning it did the trick
- The Watcher is much more flexible with the new Routes model - and that also means more ways to accidentally annoy your trackers.
Be careful: keep the progress step at the default 25% (validate in advanced).
If you set it to 1% (almost realtime) and run Plex/ Emby/Jellyfin the same time, you’ll push the huge amount of ~300 API calls to a tracker during a 60-minute movie. And yes,, some trackers will kill you and me about it.
So… think before you configure. You’re responsible for what you do. CrossWatch can do a lot (maybe way too much)… but that doesn’t mean you should enable all of it. - Be careful with profiles: in v0.9.0 they’re still experimental. They need refinement, but they should already do the job.
WIKI: Profiles and instances
WIKI: Watcher
WIKI: Insights settings
Look, I get it, nobody wants to read. But I also don’t want to answer questions with “I thought that’s what it was supposed to do.”
Please read first. If it’s still unclear, ask in Discussions. I’m happy to help Always ask before you hit “sync” and discover new ways to suffer.
✨ Highlights
- Provider Profiles / Instances
- Multiple profiles per provider (such as, Plex “Default” and “Kids”)
- Basically, you can now act as the sync hub for family or friends - including using their tracker APIs.
- Watchlist, Analyzer, Exporter, Editor updated to be profile-aware
- Insights Settings
- New modal to include/exclude Features and Provider Profiles
Watcher / Routes
- Why the new routes mode
- Configure any media server(s) with any tracker(s) and run all together
- Legacy watcher configs migrate to routes mode (Default profile auto-applied)
- UI reflects active routes
- Status shows mode and providers
Profiles & State (Core Improvements)
- Watchlist
- Aggregates from Default and all profiles
- Insights shows which profile(s) each item comes from
- Analyzer
- Understands multi-profile setups; no longer flags “instances-only” as unconfigured
- Diagnostics support newer scope formats with profile context
- Exporter
- Export modal adds Profile selector
- Export endpoints support optional
provider_instance(export per profile where supported)
- Editor
- Current State: load/save per Default and profiles
- State Import (debug): can target a specific profile
- Pair Cache editor supports modern scopes (no legacy
pair_dependency)
- State & Insights Accuracy
- Orchestrator tags synced items with source profile in
state.json - Enables correct per-profile totals and prevents blending
- Orchestrator tags synced items with source profile in
UI & Visibility
- Configured Providers - Counts configured profiles (including Default), with compact display
- Whitelisting - Whitelists include profiles and show profile names
🔧 Fixes and Improvements
- Plex Home user picker - Managed users marked as Home Prevents wrong selection / bad
account_id - Plex Watchlist (Discover)- Fixes unauthorized errors after switching Plex Home users
- Emby/Jellyfin - Allow empty password setups (issue #74)
- Clear browser cache after upgrade to avoid stale UI issues.
- Be cautious when lowering the progress step below default 25% in Routes mode – high API call volume may trigger tracker bans.
- Profile configuration is experimental; monitor behavior and consult the wiki for guidance.
- Watcher configuration migrates to new Routes mode; default profile is auto‑applied, altering observable behavior of scrobble flows.
- Profile/Instance system replaces the previous single‑profile model (requires reconfiguration of existing setups).
- Provider Profiles / Instances – multiple profiles per provider enabling sync hub for family/friends with tracker API support.
- Watcher Routes mode – configure any media server(s) with any tracker(s) and run them together; UI shows active routes and status.
Full changelog
CrossWatch v0.9.4
🔧 Fixes & Improvements
- Watcher Scrobble no longer defaults to Trakt when no sink is configured.
- Watcher If no scrobble sink is set, watching still works, we just don’t scrobble anywhere.
- Watchlist (Internal Tracker) Covers/posters now show up again in both Watchlist and Watchlist Preview
BELOW the v0.9.3 release notes:
CrossWatch v0.9.3
🔧 Fixes & Improvements
- Plex Auth / Profiles: Fixed profile settings leaking into the default profile. Profile values now stay isolated and update immediately. https://github.com/cenodude/CrossWatch/issues/80
- Plex Home Switching: Improved Home user switching logic (correctly distinguishes Home user ID vs Plex account ID) for more reliable profile/session behavior. https://github.com/cenodude/CrossWatch/issues/81
- Plex Module Cleanup: Refactored and centralized Plex sync code (shared helpers moved into
_common, removed duplication/unused code). - Maintenance: “Clear provider cache” and “Clean everything” now preserve
/config/.cw_state/id/(Plex device and auth identifiers stay intact). - Maintenance: Added “Reset all to default” Wipes local state/caches/reports/TLS, backs up
config.jsonwith a timestamp, keeps snapshots, then restarts CrossWatch.
BELOW the v0.9.2 release notes:
CrossWatch v0.9.2
Updated Now Playing card and banner to properly handle multiple streams (Watcher Routes mode).
If anything looks off after updating: Settings → Maintenance → Reset Currently Playing.
You can also run sinlgle pairs now from the main Synchronize button..
✨ Highlights
- Split “Synchronize” button (new)
- Click Synchronize to run everything (as before).
- Click the ▾ to run Sync all or run a single enabled pair directly.
🔧 Fixes & Improvements
- Scrobble Watcher: Fixed an issue where resume after pause could be missed until the next progress milestone.
- Playing card (Routes mode): Now supports multiple simultaneous streams (such as Plex and Emby to same sink)
- Playing card: Fixed the Now playing time ticker.. it now shows the time played
BELOW the v0.9.1 release notes:
CrossWatch v0.9.1
As always: do a hard refresh (CTRL+F5) - or better, clear your browser cache.
The number of times caching causes ghost bugs is basically infinite. So tripple please...do it...
🔧 Fixes & Improvements
- Emby/Jellyfin “Pick User”: Fixed a front-end bind issue where the button could do nothing.
- Strict ID matching (per pair): Optional per-pair setting to match IDs only (disables title/year fallback) for Plex/Emby/Jellyfin.
- Plex Home user history: History sync now writes to the selected Home user, with a safety guard to skip writes if scope switching fails.
- Plex Watcher - Fetch Server UUID: Fixed No server UUID by using the correct UUID endpoint.
- Insights UI counters: Fixed tab counters not updating reliably when switching features.
BELOW the v0.9.0 release notes:
CrossWatch v0.9.0 (experimental)
v0.9.0 brings a new Profile/Instance system and the new Watcher Routes model.
It’s marked experimental because profiles multiply the possible setups far beyond what older CrossWatch builds had to handle.
If your current version works and are happy: you can just wait a few versions before it's stable again..
But if you want to upgrade to test it and help the community shake out bugs, I’ll gladly take it.
Expect rough edges while I stabilize the new foundation...Look it is what it is....
If I had to sum this release up in one sentence: you can now run CrossWatch as a multi-profile sync hub for multiple friends/family and their services, even using their tracker APIs.
IMPORTANT and WARNINGS
- Clear your browser cache for this release. i had some issues with it.. cleaning it did the trick
- The Watcher is much more flexible with the new Routes model - and that also means more ways to accidentally annoy your trackers.
Be careful: keep the progress step at the default 25% (validate in advanced).
If you set it to 1% (almost realtime) and run Plex/ Emby/Jellyfin the same time, you’ll push the huge amount of ~300 API calls to a tracker during a 60-minute movie. And yes,, some trackers will kill you and me about it.
So… think before you configure. You’re responsible for what you do. CrossWatch can do a lot (maybe way too much)… but that doesn’t mean you should enable all of it. - Be careful with profiles: in v0.9.0 they’re still experimental. They need refinement, but they should already do the job.
WIKI: Profiles and instances
WIKI: Watcher
WIKI: Insights settings
Look, I get it, nobody wants to read. But I also don’t want to answer questions with “I thought that’s what it was supposed to do.”
Please read first. If it’s still unclear, ask in Discussions. I’m happy to help Always ask before you hit “sync” and discover new ways to suffer.
✨ Highlights
- Provider Profiles / Instances
- Multiple profiles per provider (such as, Plex “Default” and “Kids”)
- Basically, you can now act as the sync hub for family or friends - including using their tracker APIs.
- Watchlist, Analyzer, Exporter, Editor updated to be profile-aware
- Insights Settings
- New modal to include/exclude Features and Provider Profiles
Watcher / Routes
- Why the new routes mode
- Configure any media server(s) with any tracker(s) and run all together
- Legacy watcher configs migrate to routes mode (Default profile auto-applied)
- UI reflects active routes
- Status shows mode and providers
Profiles & State (Core Improvements)
- Watchlist
- Aggregates from Default and all profiles
- Insights shows which profile(s) each item comes from
- Analyzer
- Understands multi-profile setups; no longer flags “instances-only” as unconfigured
- Diagnostics support newer scope formats with profile context
- Exporter
- Export modal adds Profile selector
- Export endpoints support optional
provider_instance(export per profile where supported)
- Editor
- Current State: load/save per Default and profiles
- State Import (debug): can target a specific profile
- Pair Cache editor supports modern scopes (no legacy
pair_dependency)
- State & Insights Accuracy
- Orchestrator tags synced items with source profile in
state.json - Enables correct per-profile totals and prevents blending
- Orchestrator tags synced items with source profile in
UI & Visibility
- Configured Providers - Counts configured profiles (including Default), with compact display
- Whitelisting - Whitelists include profiles and show profile names
🔧 Fixes and Improvements
- Plex Home user picker - Managed users marked as Home Prevents wrong selection / bad
account_id - Plex Watchlist (Discover)- Fixes unauthorized errors after switching Plex Home users
- Emby/Jellyfin - Allow empty password setups (issue #74)
- Clear browser cache after upgrade.
- Profiles are experimental; expect rough edges.
- Default progress step should remain at 25% to avoid excessive tracker API calls.
- Experimental Provider Profiles / Instances enabling multi‑profile sync hub for family/friends
- Watcher Routes model allowing any media server(s) to be paired with any tracker(s)
- Insights Settings modal for including/excluding Features and Provider Profiles
Full changelog
CrossWatch v0.9.3
🔧 Fixes & Improvements
- Plex Auth / Profiles: Fixed profile settings leaking into the default profile. Profile values now stay isolated and update immediately. https://github.com/cenodude/CrossWatch/issues/80
- Plex Home Switching: Improved Home user switching logic (correctly distinguishes Home user ID vs Plex account ID) for more reliable profile/session behavior. https://github.com/cenodude/CrossWatch/issues/81
- Plex Module Cleanup: Refactored and centralized Plex sync code (shared helpers moved into
_common, removed duplication/unused code). - Maintenance: “Clear provider cache” and “Clean everything” now preserve
/config/.cw_state/id/(Plex device and auth identifiers stay intact). - Maintenance: Added “Reset all to default” Wipes local state/caches/reports/TLS, backs up
config.jsonwith a timestamp, keeps snapshots, then restarts CrossWatch.
BELOW the v0.9.2 release notes:
CrossWatch v0.9.2
Updated Now Playing card and banner to properly handle multiple streams (Watcher Routes mode).
If anything looks off after updating: Settings → Maintenance → Reset Currently Playing.
You can also run sinlgle pairs now from the main Synchronize button..
✨ Highlights
- Split “Synchronize” button (new)
- Click Synchronize to run everything (as before).
- Click the ▾ to run Sync all or run a single enabled pair directly.
🔧 Fixes & Improvements
- Scrobble Watcher: Fixed an issue where resume after pause could be missed until the next progress milestone.
- Playing card (Routes mode): Now supports multiple simultaneous streams (such as Plex and Emby to same sink)
- Playing card: Fixed the Now playing time ticker.. it now shows the time played
BELOW the v0.9.1 release notes:
CrossWatch v0.9.1
As always: do a hard refresh (CTRL+F5) - or better, clear your browser cache.
The number of times caching causes ghost bugs is basically infinite. So tripple please...do it...
🔧 Fixes & Improvements
- Emby/Jellyfin “Pick User”: Fixed a front-end bind issue where the button could do nothing.
- Strict ID matching (per pair): Optional per-pair setting to match IDs only (disables title/year fallback) for Plex/Emby/Jellyfin.
- Plex Home user history: History sync now writes to the selected Home user, with a safety guard to skip writes if scope switching fails.
- Plex Watcher - Fetch Server UUID: Fixed No server UUID by using the correct UUID endpoint.
- Insights UI counters: Fixed tab counters not updating reliably when switching features.
BELOW the v0.9.0 release notes:
CrossWatch v0.9.0 (experimental)
v0.9.0 brings a new Profile/Instance system and the new Watcher Routes model.
It’s marked experimental because profiles multiply the possible setups far beyond what older CrossWatch builds had to handle.
If your current version works and are happy: you can just wait a few versions before it's stable again..
But if you want to upgrade to test it and help the community shake out bugs, I’ll gladly take it.
Expect rough edges while I stabilize the new foundation...Look it is what it is....
If I had to sum this release up in one sentence: you can now run CrossWatch as a multi-profile sync hub for multiple friends/family and their services, even using their tracker APIs.
IMPORTANT and WARNINGS
- Clear your browser cache for this release. i had some issues with it.. cleaning it did the trick
- The Watcher is much more flexible with the new Routes model - and that also means more ways to accidentally annoy your trackers.
Be careful: keep the progress step at the default 25% (validate in advanced).
If you set it to 1% (almost realtime) and run Plex/ Emby/Jellyfin the same time, you’ll push the huge amount of ~300 API calls to a tracker during a 60-minute movie. And yes,, some trackers will kill you and me about it.
So… think before you configure. You’re responsible for what you do. CrossWatch can do a lot (maybe way too much)… but that doesn’t mean you should enable all of it. - Be careful with profiles: in v0.9.0 they’re still experimental. They need refinement, but they should already do the job.
WIKI: Profiles and instances
WIKI: Watcher
WIKI: Insights settings
Look, I get it, nobody wants to read. But I also don’t want to answer questions with “I thought that’s what it was supposed to do.”
Please read first. If it’s still unclear, ask in Discussions. I’m happy to help Always ask before you hit “sync” and discover new ways to suffer.
✨ Highlights
- Provider Profiles / Instances
- Multiple profiles per provider (such as, Plex “Default” and “Kids”)
- Basically, you can now act as the sync hub for family or friends - including using their tracker APIs.
- Watchlist, Analyzer, Exporter, Editor updated to be profile-aware
- Insights Settings
- New modal to include/exclude Features and Provider Profiles
Watcher / Routes
- Why the new routes mode
- Configure any media server(s) with any tracker(s) and run all together
- Legacy watcher configs migrate to routes mode (Default profile auto-applied)
- UI reflects active routes
- Status shows mode and providers
Profiles & State (Core Improvements)
- Watchlist
- Aggregates from Default and all profiles
- Insights shows which profile(s) each item comes from
- Analyzer
- Understands multi-profile setups; no longer flags “instances-only” as unconfigured
- Diagnostics support newer scope formats with profile context
- Exporter
- Export modal adds Profile selector
- Export endpoints support optional
provider_instance(export per profile where supported)
- Editor
- Current State: load/save per Default and profiles
- State Import (debug): can target a specific profile
- Pair Cache editor supports modern scopes (no legacy
pair_dependency)
- State & Insights Accuracy
- Orchestrator tags synced items with source profile in
state.json - Enables correct per-profile totals and prevents blending
- Orchestrator tags synced items with source profile in
UI & Visibility
- Configured Providers - Counts configured profiles (including Default), with compact display
- Whitelisting - Whitelists include profiles and show profile names
🔧 Fixes and Improvements
- Plex Home user picker - Managed users marked as Home Prevents wrong selection / bad
account_id - Plex Watchlist (Discover)- Fixes unauthorized errors after switching Plex Home users
- Emby/Jellyfin - Allow empty password setups (issue #74)
- Clear browser cache after upgrading to avoid stale UI artifacts.
- Be cautious with the progress step setting; default is 25% to limit tracker API calls.
- Profiles are experimental—expect rough edges and monitor for configuration issues.
- Legacy watcher configs are automatically migrated to the new Routes mode with Default profile applied.
- Multi‑profile support for each provider (e.g., Plex “Default” and “Kids”).
- Watcher Routes model allowing any media server(s) paired with any tracker(s).
- Profile‑aware Watchlist, Analyzer, Exporter, and Editor components.
Full changelog
CrossWatch v0.9.2
Updated Now Playing card and banner to properly handle multiple streams (Watcher Routes mode).
If anything looks off after updating: Settings → Maintenance → Reset Currently Playing.
You can also run sinlgle pairs now from the main Synchronize button..
✨ Highlights
- Split “Synchronize” button (new)
- Click Synchronize to run everything (as before).
- Click the ▾ to run Sync all or run a single enabled pair directly.
🔧 Fixes & Improvements
- Scrobble Watcher: Fixed an issue where resume after pause could be missed until the next progress milestone.
- Playing card (Routes mode): Now supports multiple simultaneous streams (such as Plex and Emby to same sink)
- Playing card: Fixed the Now playing time ticker.. it now shows the time played
BELOW the v0.9.1 release notes:
CrossWatch v0.9.1
As always: do a hard refresh (CTRL+F5) - or better, clear your browser cache.
The number of times caching causes ghost bugs is basically infinite. So tripple please...do it...
🔧 Fixes & Improvements
- Emby/Jellyfin “Pick User”: Fixed a front-end bind issue where the button could do nothing.
- Strict ID matching (per pair): Optional per-pair setting to match IDs only (disables title/year fallback) for Plex/Emby/Jellyfin.
- Plex Home user history: History sync now writes to the selected Home user, with a safety guard to skip writes if scope switching fails.
- Plex Watcher - Fetch Server UUID: Fixed No server UUID by using the correct UUID endpoint.
- Insights UI counters: Fixed tab counters not updating reliably when switching features.
BELOW the v0.9.0 release notes:
CrossWatch v0.9.0 (experimental)
v0.9.0 brings a new Profile/Instance system and the new Watcher Routes model.
It’s marked experimental because profiles multiply the possible setups far beyond what older CrossWatch builds had to handle.
If your current version works and are happy: you can just wait a few versions before it's stable again..
But if you want to upgrade to test it and help the community shake out bugs, I’ll gladly take it.
Expect rough edges while I stabilize the new foundation...Look it is what it is....
If I had to sum this release up in one sentence: you can now run CrossWatch as a multi-profile sync hub for multiple friends/family and their services, even using their tracker APIs.
IMPORTANT and WARNINGS
- Clear your browser cache for this release. i had some issues with it.. cleaning it did the trick
- The Watcher is much more flexible with the new Routes model - and that also means more ways to accidentally annoy your trackers.
Be careful: keep the progress step at the default 25% (validate in advanced).
If you set it to 1% (almost realtime) and run Plex/ Emby/Jellyfin the same time, you’ll push the huge amount of ~300 API calls to a tracker during a 60-minute movie. And yes,, some trackers will kill you and me about it.
So… think before you configure. You’re responsible for what you do. CrossWatch can do a lot (maybe way too much)… but that doesn’t mean you should enable all of it. - Be careful with profiles: in v0.9.0 they’re still experimental. They need refinement, but they should already do the job.
WIKI: Profiles and instances
WIKI: Watcher
WIKI: Insights settings
Look, I get it, nobody wants to read. But I also don’t want to answer questions with “I thought that’s what it was supposed to do.”
Please read first. If it’s still unclear, ask in Discussions. I’m happy to help Always ask before you hit “sync” and discover new ways to suffer.
✨ Highlights
- Provider Profiles / Instances
- Multiple profiles per provider (such as, Plex “Default” and “Kids”)
- Basically, you can now act as the sync hub for family or friends - including using their tracker APIs.
- Watchlist, Analyzer, Exporter, Editor updated to be profile-aware
- Insights Settings
- New modal to include/exclude Features and Provider Profiles
Watcher / Routes
- Why the new routes mode
- Configure any media server(s) with any tracker(s) and run all together
- Legacy watcher configs migrate to routes mode (Default profile auto-applied)
- UI reflects active routes
- Status shows mode and providers
Profiles & State (Core Improvements)
- Watchlist
- Aggregates from Default and all profiles
- Insights shows which profile(s) each item comes from
- Analyzer
- Understands multi-profile setups; no longer flags “instances-only” as unconfigured
- Diagnostics support newer scope formats with profile context
- Exporter
- Export modal adds Profile selector
- Export endpoints support optional
provider_instance(export per profile where supported)
- Editor
- Current State: load/save per Default and profiles
- State Import (debug): can target a specific profile
- Pair Cache editor supports modern scopes (no legacy
pair_dependency)
- State & Insights Accuracy
- Orchestrator tags synced items with source profile in
state.json - Enables correct per-profile totals and prevents blending
- Orchestrator tags synced items with source profile in
UI & Visibility
- Configured Providers - Counts configured profiles (including Default), with compact display
- Whitelisting - Whitelists include profiles and show profile names
🔧 Fixes and Improvements
- Plex Home user picker - Managed users marked as Home Prevents wrong selection / bad
account_id - Plex Watchlist (Discover)- Fixes unauthorized errors after switching Plex Home users
- Emby/Jellyfin - Allow empty password setups (issue #74)
- Clear browser cache after upgrading.
- Legacy watcher configurations are migrated to the new Routes model with the Default profile auto‑applied; review route settings post‑upgrade.
- Be cautious with progress step configuration – setting it too low (e.g., 1%) can cause excessive API calls (~300 per tracker during a 60‑minute movie).
- Introduces an experimental Profile/Instance system that changes the core sync model; existing single‑profile setups must migrate to routes mode with default profile auto‑applied.
- Provider Profiles / Instances: support multiple profiles per provider (e.g., Plex "Default" and "Kids") enabling CrossWatch as a sync hub for family or friends, including their tracker APIs.
- Insights Settings: new modal to include/exclude Features and Provider Profiles.
- Watcher Routes model: configure any media server(s) with any tracker(s) together; legacy watcher configs automatically migrate to routes mode with default profile applied.
Full changelog
CrossWatch v0.9.1
As always: do a hard refresh (CTRL+F5) - or better, clear your browser cache.
The number of times caching causes ghost bugs is basically infinite. So tripple please...do it...
🔧 Fixes & Improvements
- Emby/Jellyfin “Pick User”: Fixed a front-end bind issue where the button could do nothing.
- Strict ID matching (per pair): Optional per-pair setting to match IDs only (disables title/year fallback) for Plex/Emby/Jellyfin.
- Plex Home user history: History sync now writes to the selected Home user, with a safety guard to skip writes if scope switching fails.
- Plex Watcher - Fetch Server UUID: Fixed No server UUID by using the correct UUID endpoint.
- Insights UI counters: Fixed tab counters not updating reliably when switching features.
BELOW the v0.9.0 release notes:
CrossWatch v0.9.0 (experimental)
v0.9.0 brings a new Profile/Instance system and the new Watcher Routes model.
It’s marked experimental because profiles multiply the possible setups far beyond what older CrossWatch builds had to handle.
If your current version works and are happy: you can just wait a few versions before it's stable again..
But if you want to upgrade to test it and help the community shake out bugs, I’ll gladly take it.
Expect rough edges while I stabilize the new foundation...Look it is what it is....
If I had to sum this release up in one sentence: you can now run CrossWatch as a multi-profile sync hub for multiple friends/family and their services, even using their tracker APIs.
IMPORTANT and WARNINGS
- Clear your browser cache for this release. i had some issues with it.. cleaning it did the trick
- The Watcher is much more flexible with the new Routes model - and that also means more ways to accidentally annoy your trackers.
Be careful: keep the progress step at the default 25% (validate in advanced).
If you set it to 1% (almost realtime) and run Plex/ Emby/Jellyfin the same time, you’ll push the huge amount of ~300 API calls to a tracker during a 60-minute movie. And yes,, some trackers will kill you and me about it.
So… think before you configure. You’re responsible for what you do. CrossWatch can do a lot (maybe way too much)… but that doesn’t mean you should enable all of it. - Be careful with profiles: in v0.9.0 they’re still experimental. They need refinement, but they should already do the job.
WIKI: Profiles and instances
WIKI: Watcher
WIKI: Insights settings
Look, I get it, nobody wants to read. But I also don’t want to answer questions with “I thought that’s what it was supposed to do.”
Please read first. If it’s still unclear, ask in Discussions. I’m happy to help Always ask before you hit “sync” and discover new ways to suffer.
✨ Highlights
- Provider Profiles / Instances
- Multiple profiles per provider (such as, Plex “Default” and “Kids”)
- Basically, you can now act as the sync hub for family or friends - including using their tracker APIs.
- Watchlist, Analyzer, Exporter, Editor updated to be profile-aware
- Insights Settings
- New modal to include/exclude Features and Provider Profiles
Watcher / Routes
- Why the new routes mode
- Configure any media server(s) with any tracker(s) and run all together
- Legacy watcher configs migrate to routes mode (Default profile auto-applied)
- UI reflects active routes
- Status shows mode and providers
Profiles & State (Core Improvements)
- Watchlist
- Aggregates from Default and all profiles
- Insights shows which profile(s) each item comes from
- Analyzer
- Understands multi-profile setups; no longer flags “instances-only” as unconfigured
- Diagnostics support newer scope formats with profile context
- Exporter
- Export modal adds Profile selector
- Export endpoints support optional
provider_instance(export per profile where supported)
- Editor
- Current State: load/save per Default and profiles
- State Import (debug): can target a specific profile
- Pair Cache editor supports modern scopes (no legacy
pair_dependency)
- State & Insights Accuracy
- Orchestrator tags synced items with source profile in
state.json - Enables correct per-profile totals and prevents blending
- Orchestrator tags synced items with source profile in
UI & Visibility
- Configured Providers - Counts configured profiles (including Default), with compact display
- Whitelisting - Whitelists include profiles and show profile names
🔧 Fixes and Improvements
- Plex Home user picker - Managed users marked as Home Prevents wrong selection / bad
account_id - Plex Watchlist (Discover)- Fixes unauthorized errors after switching Plex Home users
- Emby/Jellyfin - Allow empty password setups (issue #74)
- Clear browser cache after upgrading.
- Legacy watcher configurations are automatically migrated to the new Routes mode; default profile is applied.
- Be cautious with low progress‑step settings (e.g., 1%) as they can generate ~300 API calls per hour for Plex/Emby/Jellyfin, potentially triggering tracker rate limits.
- Provider Profiles/Instances allowing multiple per‑provider setups (e.g., Plex "Default" and "Kids")
- Watcher Routes model enabling any media server to be paired with any tracker in a unified config
- Insights Settings modal for including/excluding features and provider profiles
Full changelog
CrossWatch v0.9.0 (experimental)
v0.9.0 brings a new Profile/Instance system and the new Watcher Routes model.
It’s marked experimental because profiles multiply the possible setups far beyond what older CrossWatch builds had to handle.
If your current version works and are happy: you can just wait a few versions before it's stable again..
But if you want to upgrade to test it and help the community shake out bugs, I’ll gladly take it.
Expect rough edges while I stabilize the new foundation...Look it is what it is....
If I had to sum this release up in one sentence: you can now run CrossWatch as a multi-profile sync hub for multiple friends/family and their services, even using their tracker APIs.
IMPORTANT and WARNINGS
- Clear your browser cache for this release. i had some issues with it.. cleaning it did the trick
- The Watcher is much more flexible with the new Routes model - and that also means more ways to accidentally annoy your trackers.
Be careful: keep the progress step at the default 25% (validate in advanced).
If you set it to 1% (almost realtime) and run Plex/ Emby/Jellyfin the same time, you’ll push the huge amount of ~300 API calls to a tracker during a 60-minute movie. And yes,, some trackers will kill you and me about it.
So… think before you configure. You’re responsible for what you do. CrossWatch can do a lot (maybe way too much)… but that doesn’t mean you should enable all of it. - Be careful with profiles: in v0.9.0 they’re still experimental. They need refinement, but they should already do the job.
WIKI: Profiles and instances
WIKI: Watcher
WIKI: Insights settings
Look, I get it, nobody wants to read. But I also don’t want to answer questions with “I thought that’s what it was supposed to do.”
Please read first. If it’s still unclear, ask in Discussions. I’m happy to help Always ask before you hit “sync” and discover new ways to suffer.
✨ Highlights
- Provider Profiles / Instances
- Multiple profiles per provider (such as, Plex “Default” and “Kids”)
- Basically, you can now act as the sync hub for family or friends - including using their tracker APIs.
- Watchlist, Analyzer, Exporter, Editor updated to be profile-aware
- Insights Settings
- New modal to include/exclude Features and Provider Profiles
Watcher / Routes
- Why the new routes mode
- Configure any media server(s) with any tracker(s) and run all together
- Legacy watcher configs migrate to routes mode (Default profile auto-applied)
- UI reflects active routes
- Status shows mode and providers
Profiles & State (Core Improvements)
- Watchlist
- Aggregates from Default and all profiles
- Insights shows which profile(s) each item comes from
- Analyzer
- Understands multi-profile setups; no longer flags “instances-only” as unconfigured
- Diagnostics support newer scope formats with profile context
- Exporter
- Export modal adds Profile selector
- Export endpoints support optional
provider_instance(export per profile where supported)
- Editor
- Current State: load/save per Default and profiles
- State Import (debug): can target a specific profile
- Pair Cache editor supports modern scopes (no legacy
pair_dependency)
- State & Insights Accuracy
- Orchestrator tags synced items with source profile in
state.json - Enables correct per-profile totals and prevents blending
- Orchestrator tags synced items with source profile in
UI & Visibility
- Configured Providers - Counts configured profiles (including Default), with compact display
- Whitelisting - Whitelists include profiles and show profile names
🔧 Fixes and Improvements
- Plex Home user picker - Managed users marked as Home Prevents wrong selection / bad
account_id - Plex Watchlist (Discover)- Fixes unauthorized errors after switching Plex Home users
- Emby/Jellyfin - Allow empty password setups (issue #74)
Fixed incorrect Restart required and Show/Hide Ask AI banners.
Full changelog
CrossWatch - v0.8.2
Mostly small bug fixes in this release. The v0.8.x line is primarily focused on stability.
In the background, work is ongoing on v0.9.0, which will introduce Profiles with support for multi-server and multi-account setups.
Progress/status: https://github.com/cenodude/CrossWatch/issues/73
🔧 Fixes & Improvements
-
Protocol switch restart banner
- The Restart required prompt now clears correctly
- Added a 1-minute TTL fallback logic to auto-remove stale restart prompts
-
Show/Hide Ask AI restart banner
- Fixed cases where toggling “Show/Hide Ask AI” could trigger the wrong banner (or no banner)
- “Restart now” now works reliably
- Added TMDb (sync) provider supporting Watchlist and Ratings for Movies, Shows, Episodes
Full changelog
CrossWatch - v0.8.1
CrossWatch now supports a new sync provider: TMDb (sync).
TMDb is available both as a metadata provider and as a sync provider but they’re separate features and need different configuration.
✨ Highlights
- TMDb (sync) Provider (new)
- Link your TMDb API in Settings/Authentication and use it as a sync source and/or target.
- Supported features:
- Watchlist
- Ratings Movies, Shows, Episodes (no seasons)
🔧 Fixes & Improvements
-
SIMKL Anime Movies (ID and Type Handling)
- Anime entries that are actually movies are now treated as Movies for matching and syncing.
- Improves syncing to providers that rely on movie IDs, reducing wrong matches.
-
ProbesAPI
- Throttled probe refreshes so repeated requests wouldn’t overwhelm the system.
📚 Wiki
-
TMDb authentication - read here
-
TMDb sync adapter - read here
- Self‑signed HTTPS certificates do NOT work with Webhooks; use a trusted cert via reverse proxy for webhook functionality.
- After switching to HTTPS, update all external references (webhooks, redirect URLs) to the new secure URL.
- Experimental Snapshots with rollback (merge or clear modes)
- HTTPS support with UI TLS manager, certificate download, and regeneration
- About/Help Assistance integrated wiki and AI‑powered help (HTTPS only)
Full changelog
CrossWatch - v0.8.0
Welcome at v0.8: I've added also some nice new features such as Snapshots, HTTPS support and help assistance. Also, CW has improved SIMKL anime support for shows: sync is now TVDB-first to avoid season mismatches. However, Anime is still a work in progress for now.
For better security (and a few extra features), I recommend using HTTPS.
Ideally use a reverse proxy, but you can also enable HTTPS in CW. Just note: webhooks will NOT work with self-signed certificates.
Do NOT forget that after switching to HTTPS anything that points at your CrossWatch URL must be updated (webhooks and redirect URLs)
You may have noticed: I moved the wiki to a new site: https://wiki.crosswatch.app
If you use HTTPS for CW, the new wiki is fully integrated, including chatbot, from within CW.
✨ Highlights
-
- Create snapshots and let you rollback provider data if something goes wrong.
- Captures: Watchlist / Ratings / History (or All features)
- Two restore modes: Merge (safe): only adds missing items and Clear (destructive): wipes the dataset first, then restores
-
HTTPS Support (new, experimental)
- CW can now run over HTTPS (self-signed by default), and you can manage TLS settings from the UI.
- Note: self-signed certificates does NOT work with Webhooks!
- Next to Protocol there’s an Advanced button that opens the TLS manager:
- View current certificate status.
- Download the
.crtso you can trust the certificate on your device/browser (fewer angry browser warnings). - Optional: Regenerate a self-signed certificate.
- Optional: configure custom cert/key paths (for your own certificates / reverse proxy setups).
Tip: For a “real” trusted certificate on the internet, use a reverse proxy (Caddy/Nginx/Traefik) with Let’s Encrypt and run CW behind it.
- About/Help Assistance (new)
- About/Help Opens the wiki (wiki.crosswatch.app) - and when you’re on HTTPS, it’s integrated directly into CW.
- Ask AI (only works in HTTPS) - The Ask AI button lets you quickly look up CW help and docs.
🔧 Fixes & Improvements
- Plex history sync is faster when you whitelist libraries
- If you configured Plex whitelisting, CW now fetches history only for those libraries (server-side filtering).
- Big speed-up on large servers, because it no longer loads your entire Plex history and filters it locally.
- Authentication now supports multiple sessions (multi-device login)
- You can stay logged in on multiple devices/browsers at the same time.
- Sync results now show only real changes in UI
- The UI no longer shows “added” items that were only part of a snapshot/cache.
- When nothing was applied, the summary stays at 0 changes (as it should).
- Trakt API compliance (Feb 2026 readiness) - CrossWatch is compliant with Trakt’s upcoming pagination requirements.
- SIMKL Anime (History) – TVDB season mapping - Uses SIMKL’s mapping so anime episodes.
- Better matching to Plex/Emby/Jellyfin (title hints) - English-style slug (TVDB/Trakt), CW uses that as a title hint.
- SIMKL ratings and watchlist are more accurate - Prefer TVDB-based matching for anime where available.
- Ratings updates now sync correctly - Changing a rating now updates on the other provider too.
- Fix: Webhooks were being blocked by the auth gate, so they became unreachable once authentication was enabled.
- Fix: CW tracker in pair would disable sync button - When CW tracker was in a pair, the sync button would be greyed out.
- Compact mobile dashboard view with optional toggle between Compact and Full UI
- Option to install CrossWatch as a native app on Android and iPhone (requires reverse proxy with public SSL)
- Mobile‑optimized “Now Playing” card layout for smaller screens
Full changelog
CrossWatch - v0.7.8
Better mobile experience: CrossWatch now shows a compact mobile dashboard view on phones, focused on what matters most.
✨ Highlights
-
Mobile dashboard support
- Phone-friendly overview that prioritizes only the essentials
- Shows Statistics and Recent syncs and the Scrobble “Now Playing” card
- Optional quick toggle to switch between Compact and Full UI on mobile
- Optional install as app in Android and iPhone. Requires reverse proxy with public SSL certificate
-
Watcher “Now Playing” improvements (for mobile)
- Better layout and spacing for smaller screens
- Cleaner, more readable card content on phones
🔧 Fixes & Improvements
-
SIMKL ratings titles
- Fixed SIMKL ratings parsing so titles/years are read correctly
- Removes “IMDB:tt123…” placeholder titles in ratings sync summaries
-
Security UI feedback
- Password confirmation now shows a clear error when it doesn’t match
- Prevents saving until the issue is fixed (no more silent “nothing happened”)
CrossWatch - v0.7.6
This update fixes the episode titles in the UI for History & Ratings.
Adds optional authentication for people who don’t want CrossWatch UI wide open.
✨ Highlights
- Security: Optional UI authentication
- Enable it in Settings (UI / Security / CW Tracker) turn on authentication and set a username and password.
- 30-day “remember me” login once you sign in.
🔧 Fixes & Improvements
-
UI: History & Ratings episode titles
- Correct episode formatting: episodes now show as
Show - S01E01where possible - No more “title flip” after loading: the dashboard no longer overwrites the run summary spotlight items with a simplified version from the insights refresh.
- More consistent spotlight details: CW keeps episode metadata (show name and season/episode) so the lanes stay stable and readable.
- Correct episode formatting: episodes now show as
-
UI: Provider library whitelists no longer reset
- Whitelists are preserved on Save after restarts: Plex/Emby/Jellyfin library selections won’t get wiped just because you restarted the container and hit Save.
CrossWatch - v0.7.5
Sorry people, I normally don’t push two updates in a day, but this one brings some nice performance boosts. Didn’t want to make you wait.
🔧 Fixes & Improvements
-
Performance & stability
- Less CPU usage when idle: the server no longer keeps re-reading and re-decoding the same big JSON “state” file over and over.
- Faster dashboard updates: run summaries (the “lanes” / timeline view) are now cached and only recalculated when something actually changed.
- Smoother streaming updates: the live status stream uses a lightweight change-check instead of repeatedly rebuilding huge JSON strings.
-
Watchers (Plex / Jellyfin / Emby)
- Smarter polling: watchers back off when nothing is playing, so they don’t waste cycles.
- Fewer redundant lookups: TV show ID lookups are cached, so episode scrobbles don’t trigger extra network calls all the time.
- Cleaner event output: fewer duplicate start/pause/stop events, which makes the sync timeline less noisy.
-
UI (Synchronize button)
- Returning to the main screen now triggers an immediate refresh, so the Synchronize button becomes available right away.
- More reliable enable/disable logic: the button state is based on real conditions.
CrossWatch - v0.7.4
🔧 Fixes & Improvements
-
Optimalizations
- The core script now loads only what’s needed for the current screen.
- CSS cleanup: branding styles are merged and more consistent.
- Removed duplicate progress handling so the progress bar and sync timeline behave more reliably.
- Removed leftover/unused code that could cause small edge-case glitches.
-
Cleaner provider icons in Settings
- Provider logos now only show when that provider is actually configured (instead of showing everything).
- Scrobbler icons now reflect your enabled Watcher provider and selected sinks (instead of showing everything).
-
SIMKL and Trakt auth behaves better after approval
- “Waiting for token” polling is smarter: ~2s intervals for ~30s, then it slows down.
- Switching back to the CrossWatch tab triggers an immediate check (no unnecessary waiting).
-
SIMKL history sync includes completed shows and anime
- Fixed an issue where shows/anime could disappear from the snapshot after finishing the final episode.
-
Fewer API calls, faster syncs (new batching controls)
- Added provider-specific batching controls so large syncs can run with fewer requests.
- Default behavior stays the same (safe 100), but you can override per provider when needed (such as SIMKL).
- Config-only (for now): currently only SIMKL is wired up; other providers will keep the default until they’re tested and added.
read here for updated orchestrator
Example config.json
"apply_chunk_size_by_provider": {
"SIMKL": 500, <-- currently added
"TRAKT": 500,
"MDBLIST": 500
}
CrossWatch - v0.7.3
🔧 Fixes & Improvements
-
Auth providers now load only when needed
- Authentication provider are no longer loaded on every page load.
- This reduces initial network requests and keeps the UI lighter.
-
Orchestrator: history
- Fixed a bug where episode entries could be mistaken as “already synced” when the show existed on target provider.
- Fixed a matching bug that could cause ghost changes during history sync (planned adds that end up being skipped).
- Result: more accurate history syncs and less noisy sync summaries.
-
Plex authentication UI improvement
- Clear warning when Plex Media Server (PMS) can’t be reached
- If Plex account auth succeeds but the configured PMS URL is wrong/unreachable, CrossWatch now shows:
- Connected, but PMS is not reachable - validate settings.
-
MDBList provider history sync is more stable
- No more “remove everything / add everything back” loops.
- MDBList show/season summary entries are ignored; only real history items are synced.
- Sync summary no longer shows fake “skipped” items when MDBList processes bulk updates.
- Prevents fake “+1 rating” changes caused by invalid IMDb IDs.
CrossWatch - v0.7.2
🔧 Fixes & Improvements
-
API and performance improvement (SIMKL/TRAKT/MDBLIST)
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
- Episode entries from now on display as
Show Name - S01E01and not the episode title anymore.
- Episode entries from now on display as
- Prevents hitting daily API limits and avoids API request spikes on first syncs.
- In future releases, I’ll aim to reduce API calls even further.
- Thanks to @Entixs for the bug report.
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
-
Episode display regression in the Sync summary / History spotlight
- Episode items now show the show name (
South Park - S01E05) instead of onlyS01E05.
- Episode items now show the show name (
-
Plex history sync is faster and lighter
- The optional “include marked watched” hydration no longer scans entire Plex libraries.
- CrossWatch now requests only watched items, paginates, and stops once it reaches older plays.
- Big speed-up on large libraries and fewer Plex API calls after the first run.
-
Web UI network usage reduced
- The Sync status screen now prefers live updates and uses polling only as a fallback.
- The Pairs list refresh is now event-driven (updates when something changes), with a slow safety refresh.
- Scheduler banner updates are now throttled to prevent bursty refresh storms from focus/tab events.
- “Currently watching” UI updates are de-duplicated
-
Pair-scoped tombstones
- Tombstones are now pair-scoped and stored under
.cw_state, preventing “delete memory” from one provider pair blocking another. - Fixes cases where shows (and full seasons) could stay stuck even after a reset.
- Tombstones are now pair-scoped and stored under
CrossWatch - v0.7.1
🔧 Fixes & Improvements
-
Big performance fix
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
- Thanks to @jabrown93 for opening the bug report and debugging.
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
-
AniList linking
- Improved the AniList login/link flow so it doesn’t keep “refreshing” in the background.
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
- Optional UI authentication added to prevent unauthenticated access to the CrossWatch UI.
- Settings UI overhaul – cleaner navigation, grouped sections for Media servers (Plex/Jellyfin/Emby), Scrobbler, Metadata, Scheduling and General Settings.
- Optional UI authentication – can be enabled in Settings > UI > Security > CW Tracker with username/password and 30‑day "remember me" login.
Full changelog
CrossWatch - v0.7.7
This update overhauls the Settings UI to make it much easier to navigate.
Plex, Emby, Jellyfin, Scrobbler (Webhooks and Watcher), Metadata, Scheduling, and general Settings are now grouped and organized more clearly.
✨ Highlights
- Settings UI overhaul
- Cleaner navigation with better grouping and less scrolling
- Media servers: Plex / Jellyfin / Emby
- Scrobbler: Webhooks and Watcher, now easier to manage
- Metadata and Scheduling reorganized for faster access
- General Settings improved layout and discoverability
CrossWatch - v0.7.6
This update fixes the episode titles in the UI for History & Ratings.
Adds optional authentication for people who don’t want CrossWatch UI wide open.
✨ Highlights
- Security: Optional UI authentication
- Enable it in Settings (UI / Security / CW Tracker) turn on authentication and set a username and password.
- 30-day “remember me” login once you sign in.
🔧 Fixes & Improvements
-
UI: History & Ratings episode titles
- Correct episode formatting: episodes now show as
Show - S01E01where possible - No more “title flip” after loading: the dashboard no longer overwrites the run summary spotlight items with a simplified version from the insights refresh.
- More consistent spotlight details: CW keeps episode metadata (show name and season/episode) so the lanes stay stable and readable.
- Correct episode formatting: episodes now show as
-
UI: Provider library whitelists no longer reset
- Whitelists are preserved on Save after restarts: Plex/Emby/Jellyfin library selections won’t get wiped just because you restarted the container and hit Save.
CrossWatch - v0.7.5
Sorry people, I normally don’t push two updates in a day, but this one brings some nice performance boosts. Didn’t want to make you wait.
🔧 Fixes & Improvements
-
Performance & stability
- Less CPU usage when idle: the server no longer keeps re-reading and re-decoding the same big JSON “state” file over and over.
- Faster dashboard updates: run summaries (the “lanes” / timeline view) are now cached and only recalculated when something actually changed.
- Smoother streaming updates: the live status stream uses a lightweight change-check instead of repeatedly rebuilding huge JSON strings.
-
Watchers (Plex / Jellyfin / Emby)
- Smarter polling: watchers back off when nothing is playing, so they don’t waste cycles.
- Fewer redundant lookups: TV show ID lookups are cached, so episode scrobbles don’t trigger extra network calls all the time.
- Cleaner event output: fewer duplicate start/pause/stop events, which makes the sync timeline less noisy.
-
UI (Synchronize button)
- Returning to the main screen now triggers an immediate refresh, so the Synchronize button becomes available right away.
- More reliable enable/disable logic: the button state is based on real conditions.
CrossWatch - v0.7.4
🔧 Fixes & Improvements
-
Optimalizations
- The core script now loads only what’s needed for the current screen.
- CSS cleanup: branding styles are merged and more consistent.
- Removed duplicate progress handling so the progress bar and sync timeline behave more reliably.
- Removed leftover/unused code that could cause small edge-case glitches.
-
Cleaner provider icons in Settings
- Provider logos now only show when that provider is actually configured (instead of showing everything).
- Scrobbler icons now reflect your enabled Watcher provider and selected sinks (instead of showing everything).
-
SIMKL and Trakt auth behaves better after approval
- “Waiting for token” polling is smarter: ~2s intervals for ~30s, then it slows down.
- Switching back to the CrossWatch tab triggers an immediate check (no unnecessary waiting).
-
SIMKL history sync includes completed shows and anime
- Fixed an issue where shows/anime could disappear from the snapshot after finishing the final episode.
-
Fewer API calls, faster syncs (new batching controls)
- Added provider-specific batching controls so large syncs can run with fewer requests.
- Default behavior stays the same (safe 100), but you can override per provider when needed (such as SIMKL).
- Config-only (for now): currently only SIMKL is wired up; other providers will keep the default until they’re tested and added.
read here for updated orchestrator
Example config.json
"apply_chunk_size_by_provider": {
"SIMKL": 500, <-- currently added
"TRAKT": 500,
"MDBLIST": 500
}
CrossWatch - v0.7.3
🔧 Fixes & Improvements
-
Auth providers now load only when needed
- Authentication provider are no longer loaded on every page load.
- This reduces initial network requests and keeps the UI lighter.
-
Orchestrator: history
- Fixed a bug where episode entries could be mistaken as “already synced” when the show existed on target provider.
- Fixed a matching bug that could cause ghost changes during history sync (planned adds that end up being skipped).
- Result: more accurate history syncs and less noisy sync summaries.
-
Plex authentication UI improvement
- Clear warning when Plex Media Server (PMS) can’t be reached
- If Plex account auth succeeds but the configured PMS URL is wrong/unreachable, CrossWatch now shows:
- Connected, but PMS is not reachable - validate settings.
-
MDBList provider history sync is more stable
- No more “remove everything / add everything back” loops.
- MDBList show/season summary entries are ignored; only real history items are synced.
- Sync summary no longer shows fake “skipped” items when MDBList processes bulk updates.
- Prevents fake “+1 rating” changes caused by invalid IMDb IDs.
CrossWatch - v0.7.2
🔧 Fixes & Improvements
-
API and performance improvement (SIMKL/TRAKT/MDBLIST)
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
- Episode entries from now on display as
Show Name - S01E01and not the episode title anymore.
- Episode entries from now on display as
- Prevents hitting daily API limits and avoids API request spikes on first syncs.
- In future releases, I’ll aim to reduce API calls even further.
- Thanks to @Entixs for the bug report.
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
-
Episode display regression in the Sync summary / History spotlight
- Episode items now show the show name (
South Park - S01E05) instead of onlyS01E05.
- Episode items now show the show name (
-
Plex history sync is faster and lighter
- The optional “include marked watched” hydration no longer scans entire Plex libraries.
- CrossWatch now requests only watched items, paginates, and stops once it reaches older plays.
- Big speed-up on large libraries and fewer Plex API calls after the first run.
-
Web UI network usage reduced
- The Sync status screen now prefers live updates and uses polling only as a fallback.
- The Pairs list refresh is now event-driven (updates when something changes), with a slow safety refresh.
- Scheduler banner updates are now throttled to prevent bursty refresh storms from focus/tab events.
- “Currently watching” UI updates are de-duplicated
-
Pair-scoped tombstones
- Tombstones are now pair-scoped and stored under
.cw_state, preventing “delete memory” from one provider pair blocking another. - Fixes cases where shows (and full seasons) could stay stuck even after a reset.
- Tombstones are now pair-scoped and stored under
CrossWatch - v0.7.1
🔧 Fixes & Improvements
-
Big performance fix
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
- Thanks to @jabrown93 for opening the bug report and debugging.
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
-
AniList linking
- Improved the AniList login/link flow so it doesn’t keep “refreshing” in the background.
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
- Optional UI authentication via Settings (UI / Security / CW Tracker) with username/password and 30‑day remember me
Full changelog
CrossWatch - v0.7.6
This update fixes the episode titles in the UI for History & Ratings.
Adds optional authentication for people who don’t want CrossWatch UI wide open.
✨ Highlights
- Security: Optional UI authentication
- Enable it in Settings (UI / Security / CW Tracker) turn on authentication and set a username and password.
- 30-day “remember me” login once you sign in.
🔧 Fixes & Improvements
-
UI: History & Ratings episode titles
- Correct episode formatting: episodes now show as
Show - S01E01where possible - No more “title flip” after loading: the dashboard no longer overwrites the run summary spotlight items with a simplified version from the insights refresh.
- More consistent spotlight details: CW keeps episode metadata (show name and season/episode) so the lanes stay stable and readable.
- Correct episode formatting: episodes now show as
-
UI: Provider library whitelists no longer reset
- Whitelists are preserved on Save after restarts: Plex/Emby/Jellyfin library selections won’t get wiped just because you restarted the container and hit Save.
CrossWatch - v0.7.5
Sorry people, I normally don’t push two updates in a day, but this one brings some nice performance boosts. Didn’t want to make you wait.
🔧 Fixes & Improvements
-
Performance & stability
- Less CPU usage when idle: the server no longer keeps re-reading and re-decoding the same big JSON “state” file over and over.
- Faster dashboard updates: run summaries (the “lanes” / timeline view) are now cached and only recalculated when something actually changed.
- Smoother streaming updates: the live status stream uses a lightweight change-check instead of repeatedly rebuilding huge JSON strings.
-
Watchers (Plex / Jellyfin / Emby)
- Smarter polling: watchers back off when nothing is playing, so they don’t waste cycles.
- Fewer redundant lookups: TV show ID lookups are cached, so episode scrobbles don’t trigger extra network calls all the time.
- Cleaner event output: fewer duplicate start/pause/stop events, which makes the sync timeline less noisy.
-
UI (Synchronize button)
- Returning to the main screen now triggers an immediate refresh, so the Synchronize button becomes available right away.
- More reliable enable/disable logic: the button state is based on real conditions.
CrossWatch - v0.7.4
🔧 Fixes & Improvements
-
Optimalizations
- The core script now loads only what’s needed for the current screen.
- CSS cleanup: branding styles are merged and more consistent.
- Removed duplicate progress handling so the progress bar and sync timeline behave more reliably.
- Removed leftover/unused code that could cause small edge-case glitches.
-
Cleaner provider icons in Settings
- Provider logos now only show when that provider is actually configured (instead of showing everything).
- Scrobbler icons now reflect your enabled Watcher provider and selected sinks (instead of showing everything).
-
SIMKL and Trakt auth behaves better after approval
- “Waiting for token” polling is smarter: ~2s intervals for ~30s, then it slows down.
- Switching back to the CrossWatch tab triggers an immediate check (no unnecessary waiting).
-
SIMKL history sync includes completed shows and anime
- Fixed an issue where shows/anime could disappear from the snapshot after finishing the final episode.
-
Fewer API calls, faster syncs (new batching controls)
- Added provider-specific batching controls so large syncs can run with fewer requests.
- Default behavior stays the same (safe 100), but you can override per provider when needed (such as SIMKL).
- Config-only (for now): currently only SIMKL is wired up; other providers will keep the default until they’re tested and added.
read here for updated orchestrator
Example config.json
"apply_chunk_size_by_provider": {
"SIMKL": 500, <-- currently added
"TRAKT": 500,
"MDBLIST": 500
}
CrossWatch - v0.7.3
🔧 Fixes & Improvements
-
Auth providers now load only when needed
- Authentication provider are no longer loaded on every page load.
- This reduces initial network requests and keeps the UI lighter.
-
Orchestrator: history
- Fixed a bug where episode entries could be mistaken as “already synced” when the show existed on target provider.
- Fixed a matching bug that could cause ghost changes during history sync (planned adds that end up being skipped).
- Result: more accurate history syncs and less noisy sync summaries.
-
Plex authentication UI improvement
- Clear warning when Plex Media Server (PMS) can’t be reached
- If Plex account auth succeeds but the configured PMS URL is wrong/unreachable, CrossWatch now shows:
- Connected, but PMS is not reachable - validate settings.
-
MDBList provider history sync is more stable
- No more “remove everything / add everything back” loops.
- MDBList show/season summary entries are ignored; only real history items are synced.
- Sync summary no longer shows fake “skipped” items when MDBList processes bulk updates.
- Prevents fake “+1 rating” changes caused by invalid IMDb IDs.
CrossWatch - v0.7.2
🔧 Fixes & Improvements
-
API and performance improvement (SIMKL/TRAKT/MDBLIST)
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
- Episode entries from now on display as
Show Name - S01E01and not the episode title anymore.
- Episode entries from now on display as
- Prevents hitting daily API limits and avoids API request spikes on first syncs.
- In future releases, I’ll aim to reduce API calls even further.
- Thanks to @Entixs for the bug report.
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
-
Episode display regression in the Sync summary / History spotlight
- Episode items now show the show name (
South Park - S01E05) instead of onlyS01E05.
- Episode items now show the show name (
-
Plex history sync is faster and lighter
- The optional “include marked watched” hydration no longer scans entire Plex libraries.
- CrossWatch now requests only watched items, paginates, and stops once it reaches older plays.
- Big speed-up on large libraries and fewer Plex API calls after the first run.
-
Web UI network usage reduced
- The Sync status screen now prefers live updates and uses polling only as a fallback.
- The Pairs list refresh is now event-driven (updates when something changes), with a slow safety refresh.
- Scheduler banner updates are now throttled to prevent bursty refresh storms from focus/tab events.
- “Currently watching” UI updates are de-duplicated
-
Pair-scoped tombstones
- Tombstones are now pair-scoped and stored under
.cw_state, preventing “delete memory” from one provider pair blocking another. - Fixes cases where shows (and full seasons) could stay stuck even after a reset.
- Tombstones are now pair-scoped and stored under
CrossWatch - v0.7.1
🔧 Fixes & Improvements
-
Big performance fix
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
- Thanks to @jabrown93 for opening the bug report and debugging.
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
-
AniList linking
- Improved the AniList login/link flow so it doesn’t keep “refreshing” in the background.
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
- Old provider caches are cleared on upgrade; perform a hard cache refresh after migrating.
Full changelog
CrossWatch - v0.7.5
Sorry people, I normally don’t push two updates in a day, but this one brings some nice performance boosts. Didn’t want to make you wait.
🔧 Fixes & Improvements
-
Performance & stability
- Less CPU usage when idle: the server no longer keeps re-reading and re-decoding the same big JSON “state” file over and over.
- Faster dashboard updates: run summaries (the “lanes” / timeline view) are now cached and only recalculated when something actually changed.
- Smoother streaming updates: the live status stream uses a lightweight change-check instead of repeatedly rebuilding huge JSON strings.
-
Watchers (Plex / Jellyfin / Emby)
- Smarter polling: watchers back off when nothing is playing, so they don’t waste cycles.
- Fewer redundant lookups: TV show ID lookups are cached, so episode scrobbles don’t trigger extra network calls all the time.
- Cleaner event output: fewer duplicate start/pause/stop events, which makes the sync timeline less noisy.
-
UI (Synchronize button)
- Returning to the main screen now triggers an immediate refresh, so the Synchronize button becomes available right away.
- More reliable enable/disable logic: the button state is based on real conditions.
CrossWatch - v0.7.4
🔧 Fixes & Improvements
-
Optimalizations
- The core script now loads only what’s needed for the current screen.
- CSS cleanup: branding styles are merged and more consistent.
- Removed duplicate progress handling so the progress bar and sync timeline behave more reliably.
- Removed leftover/unused code that could cause small edge-case glitches.
-
Cleaner provider icons in Settings
- Provider logos now only show when that provider is actually configured (instead of showing everything).
- Scrobbler icons now reflect your enabled Watcher provider and selected sinks (instead of showing everything).
-
SIMKL and Trakt auth behaves better after approval
- “Waiting for token” polling is smarter: ~2s intervals for ~30s, then it slows down.
- Switching back to the CrossWatch tab triggers an immediate check (no unnecessary waiting).
-
SIMKL history sync includes completed shows and anime
- Fixed an issue where shows/anime could disappear from the snapshot after finishing the final episode.
-
Fewer API calls, faster syncs (new batching controls)
- Added provider-specific batching controls so large syncs can run with fewer requests.
- Default behavior stays the same (safe 100), but you can override per provider when needed (such as SIMKL).
- Config-only (for now): currently only SIMKL is wired up; other providers will keep the default until they’re tested and added.
read here for updated orchestrator
Example config.json
"apply_chunk_size_by_provider": {
"SIMKL": 500, <-- currently added
"TRAKT": 500,
"MDBLIST": 500
}
CrossWatch - v0.7.3
🔧 Fixes & Improvements
-
Auth providers now load only when needed
- Authentication provider are no longer loaded on every page load.
- This reduces initial network requests and keeps the UI lighter.
-
Orchestrator: history
- Fixed a bug where episode entries could be mistaken as “already synced” when the show existed on target provider.
- Fixed a matching bug that could cause ghost changes during history sync (planned adds that end up being skipped).
- Result: more accurate history syncs and less noisy sync summaries.
-
Plex authentication UI improvement
- Clear warning when Plex Media Server (PMS) can’t be reached
- If Plex account auth succeeds but the configured PMS URL is wrong/unreachable, CrossWatch now shows:
- Connected, but PMS is not reachable - validate settings.
-
MDBList provider history sync is more stable
- No more “remove everything / add everything back” loops.
- MDBList show/season summary entries are ignored; only real history items are synced.
- Sync summary no longer shows fake “skipped” items when MDBList processes bulk updates.
- Prevents fake “+1 rating” changes caused by invalid IMDb IDs.
CrossWatch - v0.7.2
🔧 Fixes & Improvements
-
API and performance improvement (SIMKL/TRAKT/MDBLIST)
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
- Episode entries from now on display as
Show Name - S01E01and not the episode title anymore.
- Episode entries from now on display as
- Prevents hitting daily API limits and avoids API request spikes on first syncs.
- In future releases, I’ll aim to reduce API calls even further.
- Thanks to @Entixs for the bug report.
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
-
Episode display regression in the Sync summary / History spotlight
- Episode items now show the show name (
South Park - S01E05) instead of onlyS01E05.
- Episode items now show the show name (
-
Plex history sync is faster and lighter
- The optional “include marked watched” hydration no longer scans entire Plex libraries.
- CrossWatch now requests only watched items, paginates, and stops once it reaches older plays.
- Big speed-up on large libraries and fewer Plex API calls after the first run.
-
Web UI network usage reduced
- The Sync status screen now prefers live updates and uses polling only as a fallback.
- The Pairs list refresh is now event-driven (updates when something changes), with a slow safety refresh.
- Scheduler banner updates are now throttled to prevent bursty refresh storms from focus/tab events.
- “Currently watching” UI updates are de-duplicated
-
Pair-scoped tombstones
- Tombstones are now pair-scoped and stored under
.cw_state, preventing “delete memory” from one provider pair blocking another. - Fixes cases where shows (and full seasons) could stay stuck even after a reset.
- Tombstones are now pair-scoped and stored under
CrossWatch - v0.7.1
🔧 Fixes & Improvements
-
Big performance fix
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
- Thanks to @jabrown93 for opening the bug report and debugging.
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
-
AniList linking
- Improved the AniList login/link flow so it doesn’t keep “refreshing” in the background.
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
- Update config.json to include `apply_chunk_size_by_provider` if you want custom batch sizes for SIMKL (other providers use default 100).
- Only SIMKL currently respects the new batching setting; other providers will fall back to default until tested.
- Provider icons now only display when the provider is configured (Settings)
- SIMKL auth polling adjusted to ~2 s intervals for ~30 s then slows down
- SIMKL history sync includes completed shows and anime
Full changelog
CrossWatch - v0.7.4
🔧 Fixes & Improvements
-
Optimalizations
- The core script now loads only what’s needed for the current screen.
- CSS cleanup: branding styles are merged and more consistent.
- Removed duplicate progress handling so the progress bar and sync timeline behave more reliably.
- Removed leftover/unused code that could cause small edge-case glitches.
-
Cleaner provider icons in Settings
- Provider logos now only show when that provider is actually configured (instead of showing everything).
- Scrobbler icons now reflect your enabled Watcher provider and selected sinks (instead of showing everything).
-
SIMKL and Trakt auth behaves better after approval
- “Waiting for token” polling is smarter: ~2s intervals for ~30s, then it slows down.
- Switching back to the CrossWatch tab triggers an immediate check (no unnecessary waiting).
-
SIMKL history sync includes completed shows and anime
- Fixed an issue where shows/anime could disappear from the snapshot after finishing the final episode.
-
Fewer API calls, faster syncs (new batching controls)
- Added provider-specific batching controls so large syncs can run with fewer requests.
- Default behavior stays the same (safe 100), but you can override per provider when needed (such as SIMKL).
- Config-only (for now): currently only SIMKL is wired up; other providers will keep the default until they’re tested and added.
read here for updated orchestrator
Example config.json
"apply_chunk_size_by_provider": {
"SIMKL": 500, <-- currently added
"TRAKT": 500,
"MDBLIST": 500
}
CrossWatch - v0.7.3
🔧 Fixes & Improvements
-
Auth providers now load only when needed
- Authentication provider are no longer loaded on every page load.
- This reduces initial network requests and keeps the UI lighter.
-
Orchestrator: history
- Fixed a bug where episode entries could be mistaken as “already synced” when the show existed on target provider.
- Fixed a matching bug that could cause ghost changes during history sync (planned adds that end up being skipped).
- Result: more accurate history syncs and less noisy sync summaries.
-
Plex authentication UI improvement
- Clear warning when Plex Media Server (PMS) can’t be reached
- If Plex account auth succeeds but the configured PMS URL is wrong/unreachable, CrossWatch now shows:
- Connected, but PMS is not reachable - validate settings.
-
MDBList provider history sync is more stable
- No more “remove everything / add everything back” loops.
- MDBList show/season summary entries are ignored; only real history items are synced.
- Sync summary no longer shows fake “skipped” items when MDBList processes bulk updates.
- Prevents fake “+1 rating” changes caused by invalid IMDb IDs.
CrossWatch - v0.7.2
🔧 Fixes & Improvements
-
API and performance improvement (SIMKL/TRAKT/MDBLIST)
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
- Episode entries from now on display as
Show Name - S01E01and not the episode title anymore.
- Episode entries from now on display as
- Prevents hitting daily API limits and avoids API request spikes on first syncs.
- In future releases, I’ll aim to reduce API calls even further.
- Thanks to @Entixs for the bug report.
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
-
Episode display regression in the Sync summary / History spotlight
- Episode items now show the show name (
South Park - S01E05) instead of onlyS01E05.
- Episode items now show the show name (
-
Plex history sync is faster and lighter
- The optional “include marked watched” hydration no longer scans entire Plex libraries.
- CrossWatch now requests only watched items, paginates, and stops once it reaches older plays.
- Big speed-up on large libraries and fewer Plex API calls after the first run.
-
Web UI network usage reduced
- The Sync status screen now prefers live updates and uses polling only as a fallback.
- The Pairs list refresh is now event-driven (updates when something changes), with a slow safety refresh.
- Scheduler banner updates are now throttled to prevent bursty refresh storms from focus/tab events.
- “Currently watching” UI updates are de-duplicated
-
Pair-scoped tombstones
- Tombstones are now pair-scoped and stored under
.cw_state, preventing “delete memory” from one provider pair blocking another. - Fixes cases where shows (and full seasons) could stay stuck even after a reset.
- Tombstones are now pair-scoped and stored under
CrossWatch - v0.7.1
🔧 Fixes & Improvements
-
Big performance fix
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
- Thanks to @jabrown93 for opening the bug report and debugging.
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
-
AniList linking
- Improved the AniList login/link flow so it doesn’t keep “refreshing” in the background.
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
- Auth providers now load only when needed, reducing initial network requests
- Plex UI shows clear warning when Media Server is unreachable
Full changelog
CrossWatch - v0.7.3
🔧 Fixes & Improvements
-
Auth providers now load only when needed
- Authentication provider are no longer loaded on every page load.
- This reduces initial network requests and keeps the UI lighter.
-
Orchestrator: history
- Fixed a bug where episode entries could be mistaken as “already synced” when the show existed on target provider.
- Fixed a matching bug that could cause ghost changes during history sync (planned adds that end up being skipped).
- Result: more accurate history syncs and less noisy sync summaries.
-
Plex authentication UI improvement
- Clear warning when Plex Media Server (PMS) can’t be reached
- If Plex account auth succeeds but the configured PMS URL is wrong/unreachable, CrossWatch now shows:
- Connected, but PMS is not reachable - validate settings.
-
MDBList provider history sync is more stable
- No more “remove everything / add everything back” loops.
- MDBList show/season summary entries are ignored; only real history items are synced.
- Sync summary no longer shows fake “skipped” items when MDBList processes bulk updates.
- Prevents fake “+1 rating” changes caused by invalid IMDb IDs.
CrossWatch - v0.7.2
🔧 Fixes & Improvements
-
API and performance improvement (SIMKL/TRAKT/MDBLIST)
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
- Episode entries from now on display as
Show Name - S01E01and not the episode title anymore.
- Episode entries from now on display as
- Prevents hitting daily API limits and avoids API request spikes on first syncs.
- In future releases, I’ll aim to reduce API calls even further.
- Thanks to @Entixs for the bug report.
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
-
Episode display regression in the Sync summary / History spotlight
- Episode items now show the show name (
South Park - S01E05) instead of onlyS01E05.
- Episode items now show the show name (
-
Plex history sync is faster and lighter
- The optional “include marked watched” hydration no longer scans entire Plex libraries.
- CrossWatch now requests only watched items, paginates, and stops once it reaches older plays.
- Big speed-up on large libraries and fewer Plex API calls after the first run.
-
Web UI network usage reduced
- The Sync status screen now prefers live updates and uses polling only as a fallback.
- The Pairs list refresh is now event-driven (updates when something changes), with a slow safety refresh.
- Scheduler banner updates are now throttled to prevent bursty refresh storms from focus/tab events.
- “Currently watching” UI updates are de-duplicated
-
Pair-scoped tombstones
- Tombstones are now pair-scoped and stored under
.cw_state, preventing “delete memory” from one provider pair blocking another. - Fixes cases where shows (and full seasons) could stay stuck even after a reset.
- Tombstones are now pair-scoped and stored under
CrossWatch - v0.7.1
🔧 Fixes & Improvements
-
Big performance fix
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
- Thanks to @jabrown93 for opening the bug report and debugging.
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
-
AniList linking
- Improved the AniList login/link flow so it doesn’t keep “refreshing” in the background.
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
- After upgrading, perform a hard cache refresh (Ctrl+F5) in the browser.
- Migration wipes the old global cache; ensure pair‑scoped caches are recreated post‑upgrade.
- New users receive an automated welcome message opening the settings page.
- Global orchestration state is now separated from pair‑scoped provider caches; the old cache must be wiped during migration.
- Pair‑scoped tombstones stored under `.cw_state` to prevent cross‑pair cache interference.
- MDBList adds watch history sync support and updated cleanup script with pagination fixes.
Full changelog
CrossWatch - v0.7.2
🔧 Fixes & Improvements
-
API and performance improvement (SIMKL/TRAKT/MDBLIST)
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
- Episode entries from now on display as
Show Name - S01E01and not the episode title anymore.
- Episode entries from now on display as
- Prevents hitting daily API limits and avoids API request spikes on first syncs.
- In future releases, I’ll aim to reduce API calls even further.
- Thanks to @Entixs for the bug report.
- Removed “episode title enrichment” lookups during sync. This was too API-intensive.
-
Episode display regression in the Sync summary / History spotlight
- Episode items now show the show name (
South Park - S01E05) instead of onlyS01E05.
- Episode items now show the show name (
-
Plex history sync is faster and lighter
- The optional “include marked watched” hydration no longer scans entire Plex libraries.
- CrossWatch now requests only watched items, paginates, and stops once it reaches older plays.
- Big speed-up on large libraries and fewer Plex API calls after the first run.
-
Web UI network usage reduced
- The Sync status screen now prefers live updates and uses polling only as a fallback.
- The Pairs list refresh is now event-driven (updates when something changes), with a slow safety refresh.
- Scheduler banner updates are now throttled to prevent bursty refresh storms from focus/tab events.
- “Currently watching” UI updates are de-duplicated
-
Pair-scoped tombstones
- Tombstones are now pair-scoped and stored under
.cw_state, preventing “delete memory” from one provider pair blocking another. - Fixes cases where shows (and full seasons) could stay stuck even after a reset.
- Tombstones are now pair-scoped and stored under
CrossWatch - v0.7.1
🔧 Fixes & Improvements
-
Big performance fix
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
- Thanks to @jabrown93 for opening the bug report and debugging.
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
-
AniList linking
- Improved the AniList login/link flow so it doesn’t keep “refreshing” in the background.
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
Fixed an infinite request loop when navigating to Settings that froze CrossWatch.
Full changelog
CrossWatch - v0.7.1
🔧 Fixes & Improvements
-
Big performance fix
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
- Thanks to @jabrown93 for opening the bug report and debugging.
- Fixed an issue that would spam CrossWatch with background requests, causing huge lag.
-
AniList linking
- Improved the AniList login/link flow so it doesn’t keep “refreshing” in the background.
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
Fixed an infinite /api/config request loop when navigating to Settings.
Full changelog
CrossWatch - v0.7.0
This release has many many many changes and big changes. Really big!.....
- Existing users: you’ll see a migration window. It wipes the old cache. After upgrading and migrating, do a hard cache refresh in your browser (CTR-F5)
- New users: you'll get a welcome message that opens op the settings page for you.
The orchestrator got a serious overhaul, which means bugs are more likely. So watch your step and report bugs!
It’ll take some iterations/versions to get things fine-tuned, but this major change was absolute necessary.
Analyzer and Editor still aren’t perfect, but they’re functional enough to get the job done....
IMPORTANT:
i've also fixed a real murder bug that was in v0.6.4. Going to Settings could kick off an infinite /api/config request loop, basically freezing CrossWatch.
Orchestrator state vs Pair-scoped provider caches (what changed in v0.7.0)
CrossWatch now clearly separates global orchestration state from pair-specific provider caches.
This means that the old provider caches are useless and needs to be recreated.
Global
- Baselines & drop-guard remain global per provider and feature.
- Used for sanity checksand delta safety.
- Manual blocks / allow-lists remain global.
- If you block an item via the Editor state.json, it’s filtered out of planning across all pairs where that provider and feature applies.
- If you block an item via the Editor Pair cache, it’s filtered out of planning for that specific pair only.
Pair-scoped (new provider-side caches/shadows)
- Providers now store watermarks, snapshots and write-through shadows per pair scope.
This means:
- Multiple pairs can run without overwriting each other’s cached snapshots/watermarks.
- Providers can safely reuse cached “present” indexes (when activities timestamps match) without risking cross-pair contamination.
- Less API traffic because “unchanged” states can reuse pair-local shadows instead of re-fetching full lists.
Practical impact
- Reliability improves in multi-pair setups: pairs no longer “move the clock” for each other.
- State editing still works: blocking items in the Editor still affects planning (global policy),
while pair-scoped files only affect provider caching behavior and incremental checkpoints.
🔧 Fixes & Improvements
FIX: Scrobble settings leak fix
- Navigating to Settings could previously trigger an infinite request loop to
/api/config, effectively freezing CrossWatch.
This is now fixed: the scrobbler is properly gated and no longer hammers/api/config.
Pair-specific watermarks (SIMKL, TRAKT, MDBList)
- SIMKLand MDBList now use pair-specific watermarks
- Every sync pair keeps its own “last synced” timestamps per feature (watchlist / ratings / history).
- This prevents one pair from “moving the clock forward” for another pair and accidentally skipping items.
MDBList
- New: Watch History support
- MDBList can now sync your watch history in addition to watchlist and ratings.
- i've also updated the /scripts/mdblist_cleanup.py with watch history support and fixed pagination issue with ratings.
Pair deletion cleanup
- New: Pair-scoped cache cleanup on delete
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
.cw_state. - Prevents stale cache buildup and avoids old pair artifacts lingering after cleanup.
- When a sync pair is deleted, CrossWatch now removes the corresponding pair-scoped provider cache/shadow files from
UI / Status Probes (API call reduction)
- Reduced provider API calls on browser refresh
- Some UI improvements in settings
- Scrobbe/Watcher UI fine-tuned.
Auth UI reliability
- Popup opening made consistent across providers
- SIMKL now opens a blank tab immediately on click, then navigates to the real authorize URL once fetched (prevents popup blockers from killing the flow).
- Trakt now shows a clear warning when the activation tab is blocked by the browser ("Popup blocked - allow popups and try again").
- Plex now shows the same warning when the link tab is blocked, and closes the placeholder tab if PIN creation fails.
- Some consitancy tweaks across all providers
Watcher Scrobble sinks (Trakt - MDBList - SIMKL)
- Progress throttling to reduce API calls
- Trakt, MDBList, and SIMKL scrobble sinks now support sending progress updates in steps (default: 5%*).
- This turns “~one call per 1%” into “~one call per 5%”, which is a big drop in API traffic during long plays.
- This value can be adjusted in Watcher/Advanced (1%-25%) where 1% is almost realtime (most API calls) and 25% acts more like webhooks (minimum API calls)
- Deprecated legacy webhook configuration; use the Watcher instead.
- Migration steps: remove webhooks from media servers, disable webhook in CrossWatch, enable and configure Watcher, then restart the CrossWatch container.
- Legacy webhook setup is deprecated and no longer supported; migration to Watcher required.
Full changelog
CrossWatch - v0.6.4 (hotfix)
Oeps… we had a bug that prevented new users from enabling the Watcher in the UI. That’s fixed now.
- Fixed: Watcher enable/disable now reliably saves to your configuration
- Fixed: Watcher settings no longer revert to old values while you’re editing them.
CrossWatch - v0.6.3
Jellyfin officially joined the Watcher family. We also added a new tracker sink: MDBList.
That means Watcher can now scrobble from Jellyfin, Emby, and Plex to SIMKL, Trakt, and MDBList (any combination you want).
Plex Watcher also supports real-time rating sync to SIMKL, Trakt, and MDBList.
If you have never heard of MDBList, have a look,
I also made some UI changes again, so please do a hard refresh in your browser to clear the cache (Ctrl+F5).
[!NOTE]
As of v0.6.3, the legacy webhook setup is deprecated and no longer maintained or supported.
Use the Watcher instead. Watcher replaces webhooks and is the only recommended path going forward.
It is more reliable, easier to operate, and comes with more features.If you are still on webhooks, expect no fixes and no support for webhook-related issues.
Please migrate to Watcher as soon as possible.
🔧 Fixes & Changes
- Changed: Improved the Watcher settings UI for smoother configuration.
- Changed: Standardized Watcher playback behavior across all providers (consistent start, pause, stop handling).
- Stops below 85% are treated as pause to improve resume behavior.
- High-progress pause events no longer incorrectly mark items as completed.
- New: Added API endpoint
/api/logs/watcherto view all Watcher-related log events. - New: Added a Live Event Viewer in the Watcher section.
- New: Added Watcher output to Main: View Details.
Migrate from Webhook to Watcher
- Remove the webhook from Jellyfin, Emby, or Plex.
- Restart your media server (do not skip this).
- Disable webhook in CrossWatch.
- Enable Watcher in CrossWatch, select your sinks (SIMKL, Trakt, MDBList or any mix), set your filters, and enable the autoboot slider.
- Restart the CrossWatch container to make sure everything is applied cleanly.
For Emby and Jellyfin users: configure Trakt even if you do not use it.
The Emby/Jellyfin Watcher uses a Trakt fallback when episode IDs cannot be resolved.
CrossWatch - v0.6.2
Rather huge update; v0.6.2 shows some love for anime, despite the fact that I’m not exactly an anime expert.
Consider v0.6.2 the first step into the anime world, but expect many iterations and fine-tuning in upcoming releases.
In this release we introduce SIMKL that now has Anime support and a new provider called ANILIST.
Note that Anime support is considered experimental.
[!IMPORTANT]
CrossWatch will never be 100% optimized for anime as the main focus remains Movies and Shows.
Combining both worlds into one tool is… difficult. Most providers needs IMDB/TMDB keys but Anilist only understands MAL/ANILIST IDs.
As you can imagine, in a multi-provider aware tool like CrossWatch, this bring many ... many.....many challanges.
So don’t treat CrossWatch as an anime expert tool, see it as a Movies/Shows sync tool with some experimental anime support on the side.When used in a pair (for example, SIMKL to AniList), CrossWatch will try to map each item to the correct IMDb ID so it stays compatible with other providers. If no mapping is possible, or if you import an AniList dataset into the Editor, the item may only have a MAL ID. Other providers can’t use MAL IDs, which can result in duplicates (multiple entries for the same title).
Read more here: mod_ANILIST
So regarding Anime… in a nutshell:
- Anime-compatible providers: SIMKL and a new provider AniList for Watchlist
- Default setups for Plex / Jellyfin don’t natively understand anime IDs (MAL / AniList), so CrossWatch does bridging and normalization.
- Result: most things work, but exotic anime titles may still fail.
- Anime limitations:
- CrossWatch uses TMDB for metadata, but TMDB’s anime coverage isn’t complete. Expect many missing titles and wrong/mismatched metadata for Anime titles in Watchlist preview and Watchlist section.
- Anime works, but ID mapping isn’t guaranteed, and when it falls back to MAL-only IDs, other providers may not recognize the same title, causing duplicate entries
- It’s recommended to use separate pairs for Anime and pair-level library whitelisting to minimize non-anime items.
- Even SIMKL, which does support anime, often has titles wrong. So yeah… anime is a special kind of chaos.
- i'm unable to provide any kind of user support with messages such as: 魔道祖师 has not been synced.... sorry. i just dont have the time for that.
What’s new
- SIMKL module now supports Anime (Plan to Watch).
- Added the new AniList provider for watchlist syncing.
Anime Support for SIMKL
- New: SIMKL anime lists are now supported (Plan to Watch).
- New: Anime items now keep and use anime-specific IDs (MAL / AniList / Kitsu / AniDB) where available, improving match accuracy.
- Improved: Better season/episode mapping for anime via SIMKL’s extended anime season data.
new provider: AniList
- Added AniList provider for anime watchlist sync.
- Cross-provider key strategy: items remain keyed by IMDb where available (to stay compatible with Plex/Emby/Jellyfin/SIMKL), while AniList still resolves and reads anime IDs (AniList/MAL) from
ids. - AniList will skip non-Anime items and the orchestrator will exclude them.
- AniList state persistence filters “ignored” non-anime matches to avoid polluting
state.jsonand repeated re-resolve attempts.
🔧 Fixes & Changes
- Fixed: Metadata lookups no longer misclassify anime as movies (anime is treated as show-type internally for sync logic).
- Fixed: Anime ratings and watchlist items are no longer skipped when filters are enabled.
- Fixed: Plex watcher and webhook ratings “clear stars” (unrate) now sends a proper ratings remove/0.
- Changed: In insight overview we already had M for Movies, S for Shows and now also A for Anime
- Changed: Analyzed and Editor includes Anime types and AniList is added to the list.
- Improved: Unresolved-item reporting now shows better keys for anime items.
CrossWatch - v0.6.1
🔧 Fixes & Changes
- Fixed: Importing SIMKL History from the Editor no longer creates lots of “Unknown” entries (movies and episodes now import with proper IDs).
- Fixed: SIMKL History episode imports now keep real episode titles instead of falling back to generic
S01E01style names. - Fixed: Plex watcher Live scrobble progress is now accurate even when multiple Plex users watch the same movie/show at the same time.
- Fixed: Plex webhook scrobble progress is now accurate even when multiple Plex users watch the same movie/show at the same time.
- Fixed: MDBList cleanup tool in /scripts/ - pagination now works reliably and stops correctly at the end.
- Fixed: MDBList episode ratings now store the real episode title in
state.json - Improved: SIMKL History imports are more reliable overall thanks to better handling of SIMKL’s nested data format (the Editor now reads what SIMKL actually sends).
CrossWatch - v0.6.0
Happy 2026. v0.6.0 is mainly about ratings: most provider modules were reworked to behave sanely in true two-way setups.
Big win: Plex ratings are now dramatically faster thanks to query changes (in some libraries, up to ~50×).
As with any feature release, it’s a good idea to run Maintenance to clean up your environment.
If you’re still using a config.json from older versions (< 0.5.x), you should think about rebuilding a fresh, clean config.json.
As with any feature release, expect a few bugs, don’t be surprised.
🔧 Fixes & Improvements
Orchestrator
- Two-way ratings: improved planning and execution for bidirectional ratings sync.
- Disabled pairs: disabled pairs no longer trigger snapshots (cleaner logs).
Ratings
- Plex: major query optimization (can be ~50× faster in some cases).
- Plex: improved ID resolving and lookups.
- Trakt: better season/episode ID resolving.
- SIMKL: better show/movie ID resolving.
- MDBList: fixed pagination behavior (no more “needs multiple sync runs to finish”).
Watcher & Webhooks
- Trakt sink: no more duplicate history entries
- Fixed a rare legacy-config edge case causing two “finish” events for the same playback.
- Improved duplicate-stop suppression for stop/resume/credit-skip edge cases.
- Plex ratings: fixed ratings processing in both Plex Webhook and Plex Watcher.
- Quick stops now actually stop
- Fixed debounce issues where very short sessions could miss the final stop event.
- Trakt and SIMKL scrobble state now ends cleanly even if you stop within a few seconds.
- Jellyfin webhook reliability
- Stronger protection against double “finish” events.
- More consistent stop handling during frequent progress updates.
Analyzer
- Pair-scope awareness: analyzer now respects per-pair feature scope (such as
ratings.types: ["movies","shows"]). - Out-of-scope summary: when everything is “All good”, the analyzer can still show what’s excluded by configuration
(example: “X seasons / Y episodes not synced due to pair setup”), so you don’t go hunting ghosts.
Other
- SIMKL Watchlist: added some caching improvements.
- SIMKL History: episodes now include episode titles.
- Editor: UI tweaks - season and episode shown next to TV shows.
CrossWatch - v0.5.8
This release add ratings for Plex webhook/watcher and fixes a long-standing Plex annoyance: PIN-protected Plex Home users.
CrossWatch can now switch into the correct Plex user context (even when that user has a PIN).
NOTE: This is ONLY needed for the default enabled Marked Watched plex option (manual “Mark as Watched” actions in the Plex UI).
Ratings are now supported for Plex Webhooks and Plex Watcher. CrossWatch will forward your ratings to Trakt and/or SIMKL.
updated WIKI pages:
PLEX Module
Webhook
Watcher
✨ Highlights
- Ratings for Plex Webhook and Plex Watcher are now supported
- You can now include ratings; enable it in Webhook options or Watcher options.
- For Watcher, you need to add a webhook helper, so Plex Pass is required for this option to work.
- Plex Marked Watched enhancements
- This option fetches items you manually marked as watched in Plex. Default: enabled.
- Previously it only worked reliably for the Plex Owner; Home users (with or without PINs) were not handled correctly.
🔧 Fixes & Improvements
- Correct Plex user context
- CrossWatch now attempts to switch to the configured Plex user before syncing user-specific data.
- If the user is PIN-protected, the PIN is used during the switch.
- If switching isn’t possible (wrong/missing PIN, not a Home user, etc.), CrossWatch falls back to the token user and logs why.
- If CrossWatch cannot switch to the intended user, it disables marked watched to avoid syncing the wrong profile.
- Trakt ratings
- Added retries and backoff, including
Retry-Aftersupport. - Canonical keys for seasons/episodes: cache merge/remove now includes
show_ids+ season/episode identifiers. - Improved debug logging: status codes and short response bodies on failures.
- Added retries and backoff, including
I’d love to add ratings for Emby and Jellyfin, just like Plex. The problem is: I can’t find any UI option to set user-specific ratings in Emby/Jellyfin.
Maybe I’m just blind. I do see rating-related fields in their APIs, but I’m not seeing the equivalent in the UI. Since I’m not an Emby or Jellyfin user, I might be missing something.
If you know where user ratings live in the UI (or if I’m wrong about how it works), please drop a note in the discussion so I can take another look.
CrossWatch - v0.5.7
BEST WISHES FOR 2026
This release adds Scrobble Library Whitelisting for Plex, Emby, and Jellyfin.
You can now choose exactly which libraries are allowed to generate scrobbles (Simkl/Trakt, etc.).
Configure it under settings - authentication - Plex/Emby/Jellyfin - settings.. Look for the Kermit-the-Frog green dots, that’s Scrobble.
If the scrobble whitelist is empty, CrossWatch will scrobble everything (current behavior).
This applies to both Scrobble input paths (watchers and webhooks):
- Watchers (local polling/stream watchers)
- Webhooks (server push events)
READ the WIKI regarding whitelisting
✨ Highlights
- Scrobble Library Whitelisting (Plex / Emby / Jellyfin)
- Empty whitelist = allow all (no filtering)
- New S (Scrobble) column next to H (History) and R (Ratings) in provider settings
- Emby/Jellyfin use “virtual” views, so CrossWatch resolves the correct View before applying the whitelist
- Prevents scrobbles leaking from non-whitelisted libraries
CrossWatch - v0.5.6
This release adds a new provider: Tautulli.
Tautulli is a Plex monitoring and analytics tool and NOT a tracker or media server, so CrossWatch uses it only to import your existing Plex watch history
DO NOT pair Tautulli as a destination (or “sync into” anything). It’s not a tracker/media server and will generate garbage matches: wrong IDs, tons of false items, and a bad time. Use it as a source-only helper and NEVER as a direct sync target to Plex, Jellyfin, Trakt, SIMKL, or anything else. The only correct use case: Either import the Tautulli dataset directly into the Editor, or create a one-way sync pair from Tautulli to CrossWatch Tracker.
If this all doesn’t ring a bell, you probably don’t need Tautulli imports, it’s only for a specific group of long-time Plex users with lots of existing history in Tautulli.
READ the WIKI
✨ Highlights
- New provider: Tautulli (History Import only)
- Import your historical watches from Tautulli into CrossWatch
- Tautulli is source-only: it can’t be selected as a destination
- When using Tautulli, sync is one-way only
CrossWatch - v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch - v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch - v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch - v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch - v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch - v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Deprecation warning: legacy webhook setup will receive no fixes or support; migrate to Watcher as soon as possible using the provided migration steps.
- Legacy webhook setup is deprecated and no longer maintained or supported.
- Watcher now supports scrobbling from Jellyfin to SIMKL, Trakt, and MDBList.
- Plex Watcher adds real-time rating sync to SIMKL, Trakt, and MDBList.
- New API endpoint `/api/logs/watcher` for viewing Watcher log events.
Full changelog
CrossWatch - v0.6.3
Jellyfin officially joined the Watcher family. We also added a new tracker sink: MDBList.
That means Watcher can now scrobble from Jellyfin, Emby, and Plex to SIMKL, Trakt, and MDBList (any combination you want).
Plex Watcher also supports real-time rating sync to SIMKL, Trakt, and MDBList.
If you have never heard of MDBList, have a look,
I also made some UI changes again, so please do a hard refresh in your browser to clear the cache (Ctrl+F5).
[!NOTE]
As of v0.6.3, the legacy webhook setup is deprecated and no longer maintained or supported.
Use the Watcher instead. Watcher replaces webhooks and is the only recommended path going forward.
It is more reliable, easier to operate, and comes with more features.If you are still on webhooks, expect no fixes and no support for webhook-related issues.
Please migrate to Watcher as soon as possible.
🔧 Fixes & Changes
- Changed: Improved the Watcher settings UI for smoother configuration.
- Changed: Standardized Watcher playback behavior across all providers (consistent start, pause, stop handling).
- Stops below 85% are treated as pause to improve resume behavior.
- High-progress pause events no longer incorrectly mark items as completed.
- New: Added API endpoint
/api/logs/watcherto view all Watcher-related log events. - New: Added a Live Event Viewer in the Watcher section.
- New: Added Watcher output to Main: View Details.
Migrate from Webhook to Watcher
- Remove the webhook from Jellyfin, Emby, or Plex.
- Restart your media server (do not skip this).
- Disable webhook in CrossWatch.
- Enable Watcher in CrossWatch, select your sinks (SIMKL, Trakt, MDBList or any mix), set your filters, and enable the autoboot slider.
- Restart the CrossWatch container to make sure everything is applied cleanly.
For Emby and Jellyfin users: configure Trakt even if you do not use it.
The Emby/Jellyfin Watcher uses a Trakt fallback when episode IDs cannot be resolved.
CrossWatch - v0.6.2
Rather huge update; v0.6.2 shows some love for anime, despite the fact that I’m not exactly an anime expert.
Consider v0.6.2 the first step into the anime world, but expect many iterations and fine-tuning in upcoming releases.
In this release we introduce SIMKL that now has Anime support and a new provider called ANILIST.
Note that Anime support is considered experimental.
[!IMPORTANT]
CrossWatch will never be 100% optimized for anime as the main focus remains Movies and Shows.
Combining both worlds into one tool is… difficult. Most providers needs IMDB/TMDB keys but Anilist only understands MAL/ANILIST IDs.
As you can imagine, in a multi-provider aware tool like CrossWatch, this bring many ... many.....many challanges.
So don’t treat CrossWatch as an anime expert tool, see it as a Movies/Shows sync tool with some experimental anime support on the side.When used in a pair (for example, SIMKL to AniList), CrossWatch will try to map each item to the correct IMDb ID so it stays compatible with other providers. If no mapping is possible, or if you import an AniList dataset into the Editor, the item may only have a MAL ID. Other providers can’t use MAL IDs, which can result in duplicates (multiple entries for the same title).
Read more here: mod_ANILIST
So regarding Anime… in a nutshell:
- Anime-compatible providers: SIMKL and a new provider AniList for Watchlist
- Default setups for Plex / Jellyfin don’t natively understand anime IDs (MAL / AniList), so CrossWatch does bridging and normalization.
- Result: most things work, but exotic anime titles may still fail.
- Anime limitations:
- CrossWatch uses TMDB for metadata, but TMDB’s anime coverage isn’t complete. Expect many missing titles and wrong/mismatched metadata for Anime titles in Watchlist preview and Watchlist section.
- Anime works, but ID mapping isn’t guaranteed, and when it falls back to MAL-only IDs, other providers may not recognize the same title, causing duplicate entries
- It’s recommended to use separate pairs for Anime and pair-level library whitelisting to minimize non-anime items.
- Even SIMKL, which does support anime, often has titles wrong. So yeah… anime is a special kind of chaos.
- i'm unable to provide any kind of user support with messages such as: 魔道祖师 has not been synced.... sorry. i just dont have the time for that.
What’s new
- SIMKL module now supports Anime (Plan to Watch).
- Added the new AniList provider for watchlist syncing.
Anime Support for SIMKL
- New: SIMKL anime lists are now supported (Plan to Watch).
- New: Anime items now keep and use anime-specific IDs (MAL / AniList / Kitsu / AniDB) where available, improving match accuracy.
- Improved: Better season/episode mapping for anime via SIMKL’s extended anime season data.
new provider: AniList
- Added AniList provider for anime watchlist sync.
- Cross-provider key strategy: items remain keyed by IMDb where available (to stay compatible with Plex/Emby/Jellyfin/SIMKL), while AniList still resolves and reads anime IDs (AniList/MAL) from
ids. - AniList will skip non-Anime items and the orchestrator will exclude them.
- AniList state persistence filters “ignored” non-anime matches to avoid polluting
state.jsonand repeated re-resolve attempts.
🔧 Fixes & Changes
- Fixed: Metadata lookups no longer misclassify anime as movies (anime is treated as show-type internally for sync logic).
- Fixed: Anime ratings and watchlist items are no longer skipped when filters are enabled.
- Fixed: Plex watcher and webhook ratings “clear stars” (unrate) now sends a proper ratings remove/0.
- Changed: In insight overview we already had M for Movies, S for Shows and now also A for Anime
- Changed: Analyzed and Editor includes Anime types and AniList is added to the list.
- Improved: Unresolved-item reporting now shows better keys for anime items.
CrossWatch - v0.6.1
🔧 Fixes & Changes
- Fixed: Importing SIMKL History from the Editor no longer creates lots of “Unknown” entries (movies and episodes now import with proper IDs).
- Fixed: SIMKL History episode imports now keep real episode titles instead of falling back to generic
S01E01style names. - Fixed: Plex watcher Live scrobble progress is now accurate even when multiple Plex users watch the same movie/show at the same time.
- Fixed: Plex webhook scrobble progress is now accurate even when multiple Plex users watch the same movie/show at the same time.
- Fixed: MDBList cleanup tool in /scripts/ - pagination now works reliably and stops correctly at the end.
- Fixed: MDBList episode ratings now store the real episode title in
state.json - Improved: SIMKL History imports are more reliable overall thanks to better handling of SIMKL’s nested data format (the Editor now reads what SIMKL actually sends).
CrossWatch - v0.6.0
Happy 2026. v0.6.0 is mainly about ratings: most provider modules were reworked to behave sanely in true two-way setups.
Big win: Plex ratings are now dramatically faster thanks to query changes (in some libraries, up to ~50×).
As with any feature release, it’s a good idea to run Maintenance to clean up your environment.
If you’re still using a config.json from older versions (< 0.5.x), you should think about rebuilding a fresh, clean config.json.
As with any feature release, expect a few bugs, don’t be surprised.
🔧 Fixes & Improvements
Orchestrator
- Two-way ratings: improved planning and execution for bidirectional ratings sync.
- Disabled pairs: disabled pairs no longer trigger snapshots (cleaner logs).
Ratings
- Plex: major query optimization (can be ~50× faster in some cases).
- Plex: improved ID resolving and lookups.
- Trakt: better season/episode ID resolving.
- SIMKL: better show/movie ID resolving.
- MDBList: fixed pagination behavior (no more “needs multiple sync runs to finish”).
Watcher & Webhooks
- Trakt sink: no more duplicate history entries
- Fixed a rare legacy-config edge case causing two “finish” events for the same playback.
- Improved duplicate-stop suppression for stop/resume/credit-skip edge cases.
- Plex ratings: fixed ratings processing in both Plex Webhook and Plex Watcher.
- Quick stops now actually stop
- Fixed debounce issues where very short sessions could miss the final stop event.
- Trakt and SIMKL scrobble state now ends cleanly even if you stop within a few seconds.
- Jellyfin webhook reliability
- Stronger protection against double “finish” events.
- More consistent stop handling during frequent progress updates.
Analyzer
- Pair-scope awareness: analyzer now respects per-pair feature scope (such as
ratings.types: ["movies","shows"]). - Out-of-scope summary: when everything is “All good”, the analyzer can still show what’s excluded by configuration
(example: “X seasons / Y episodes not synced due to pair setup”), so you don’t go hunting ghosts.
Other
- SIMKL Watchlist: added some caching improvements.
- SIMKL History: episodes now include episode titles.
- Editor: UI tweaks - season and episode shown next to TV shows.
CrossWatch - v0.5.8
This release add ratings for Plex webhook/watcher and fixes a long-standing Plex annoyance: PIN-protected Plex Home users.
CrossWatch can now switch into the correct Plex user context (even when that user has a PIN).
NOTE: This is ONLY needed for the default enabled Marked Watched plex option (manual “Mark as Watched” actions in the Plex UI).
Ratings are now supported for Plex Webhooks and Plex Watcher. CrossWatch will forward your ratings to Trakt and/or SIMKL.
updated WIKI pages:
PLEX Module
Webhook
Watcher
✨ Highlights
- Ratings for Plex Webhook and Plex Watcher are now supported
- You can now include ratings; enable it in Webhook options or Watcher options.
- For Watcher, you need to add a webhook helper, so Plex Pass is required for this option to work.
- Plex Marked Watched enhancements
- This option fetches items you manually marked as watched in Plex. Default: enabled.
- Previously it only worked reliably for the Plex Owner; Home users (with or without PINs) were not handled correctly.
🔧 Fixes & Improvements
- Correct Plex user context
- CrossWatch now attempts to switch to the configured Plex user before syncing user-specific data.
- If the user is PIN-protected, the PIN is used during the switch.
- If switching isn’t possible (wrong/missing PIN, not a Home user, etc.), CrossWatch falls back to the token user and logs why.
- If CrossWatch cannot switch to the intended user, it disables marked watched to avoid syncing the wrong profile.
- Trakt ratings
- Added retries and backoff, including
Retry-Aftersupport. - Canonical keys for seasons/episodes: cache merge/remove now includes
show_ids+ season/episode identifiers. - Improved debug logging: status codes and short response bodies on failures.
- Added retries and backoff, including
I’d love to add ratings for Emby and Jellyfin, just like Plex. The problem is: I can’t find any UI option to set user-specific ratings in Emby/Jellyfin.
Maybe I’m just blind. I do see rating-related fields in their APIs, but I’m not seeing the equivalent in the UI. Since I’m not an Emby or Jellyfin user, I might be missing something.
If you know where user ratings live in the UI (or if I’m wrong about how it works), please drop a note in the discussion so I can take another look.
CrossWatch - v0.5.7
BEST WISHES FOR 2026
This release adds Scrobble Library Whitelisting for Plex, Emby, and Jellyfin.
You can now choose exactly which libraries are allowed to generate scrobbles (Simkl/Trakt, etc.).
Configure it under settings - authentication - Plex/Emby/Jellyfin - settings.. Look for the Kermit-the-Frog green dots, that’s Scrobble.
If the scrobble whitelist is empty, CrossWatch will scrobble everything (current behavior).
This applies to both Scrobble input paths (watchers and webhooks):
- Watchers (local polling/stream watchers)
- Webhooks (server push events)
READ the WIKI regarding whitelisting
✨ Highlights
- Scrobble Library Whitelisting (Plex / Emby / Jellyfin)
- Empty whitelist = allow all (no filtering)
- New S (Scrobble) column next to H (History) and R (Ratings) in provider settings
- Emby/Jellyfin use “virtual” views, so CrossWatch resolves the correct View before applying the whitelist
- Prevents scrobbles leaking from non-whitelisted libraries
CrossWatch - v0.5.6
This release adds a new provider: Tautulli.
Tautulli is a Plex monitoring and analytics tool and NOT a tracker or media server, so CrossWatch uses it only to import your existing Plex watch history
DO NOT pair Tautulli as a destination (or “sync into” anything). It’s not a tracker/media server and will generate garbage matches: wrong IDs, tons of false items, and a bad time. Use it as a source-only helper and NEVER as a direct sync target to Plex, Jellyfin, Trakt, SIMKL, or anything else. The only correct use case: Either import the Tautulli dataset directly into the Editor, or create a one-way sync pair from Tautulli to CrossWatch Tracker.
If this all doesn’t ring a bell, you probably don’t need Tautulli imports, it’s only for a specific group of long-time Plex users with lots of existing history in Tautulli.
READ the WIKI
✨ Highlights
- New provider: Tautulli (History Import only)
- Import your historical watches from Tautulli into CrossWatch
- Tautulli is source-only: it can’t be selected as a destination
- When using Tautulli, sync is one-way only
CrossWatch - v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch - v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch - v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch - v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch - v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch - v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Run Maintenance → Delete Everything / Clean Everything and rebuild state after upgrading to v0.5.0.
- Remove any existing Jellyfin pairs that include ratings configuration and recreate them without the disabled feature.
- Disabled Jellyfin ratings sync in v0.5.0; feature is removed until a reliable implementation is added.
Full changelog
CrossWatch - v0.6.2
Rather huge update; v0.6.2 shows some love for anime, despite the fact that I’m not exactly an anime expert.
Consider v0.6.2 the first step into the anime world, but expect many iterations and fine-tuning in upcoming releases.
In this release we introduce SIMKL that now has Anime support and a new provider called ANILIST.
Note that Anime support is considered experimental.
[!IMPORTANT]
CrossWatch will never be 100% optimized for anime as the main focus remains Movies and Shows.
Combining both worlds into one tool is… difficult. Most providers needs IMDB/TMDB keys but Anilist only understands MAL/ANILIST IDs.
As you can imagine, in a multi-provider aware tool like CrossWatch, this bring many ... many.....many challanges.
So don’t treat CrossWatch as an anime expert tool, see it as a Movies/Shows sync tool with some experimental anime support on the side.When used in a pair (for example, SIMKL to AniList), CrossWatch will try to map each item to the correct IMDb ID so it stays compatible with other providers. If no mapping is possible, or if you import an AniList dataset into the Editor, the item may only have a MAL ID. Other providers can’t use MAL IDs, which can result in duplicates (multiple entries for the same title).
Read more here: mod_ANILIST
So regarding Anime… in a nutshell:
- Anime-compatible providers: SIMKL and a new provider AniList for Watchlist
- Default setups for Plex / Jellyfin don’t natively understand anime IDs (MAL / AniList), so CrossWatch does bridging and normalization.
- Result: most things work, but exotic anime titles may still fail.
- Anime limitations:
- CrossWatch uses TMDB for metadata, but TMDB’s anime coverage isn’t complete. Expect many missing titles and wrong/mismatched metadata for Anime titles in Watchlist preview and Watchlist section.
- Anime works, but ID mapping isn’t guaranteed, and when it falls back to MAL-only IDs, other providers may not recognize the same title, causing duplicate entries
- It’s recommended to use separate pairs for Anime and pair-level library whitelisting to minimize non-anime items.
- Even SIMKL, which does support anime, often has titles wrong. So yeah… anime is a special kind of chaos.
- i'm unable to provide any kind of user support with messages such as: 魔道祖师 has not been synced.... sorry. i just dont have the time for that.
What’s new
- SIMKL module now supports Anime (Plan to Watch).
- Added the new AniList provider for watchlist syncing.
Anime Support for SIMKL
- New: SIMKL anime lists are now supported (Plan to Watch).
- New: Anime items now keep and use anime-specific IDs (MAL / AniList / Kitsu / AniDB) where available, improving match accuracy.
- Improved: Better season/episode mapping for anime via SIMKL’s extended anime season data.
new provider: AniList
- Added AniList provider for anime watchlist sync.
- Cross-provider key strategy: items remain keyed by IMDb where available (to stay compatible with Plex/Emby/Jellyfin/SIMKL), while AniList still resolves and reads anime IDs (AniList/MAL) from
ids. - AniList will skip non-Anime items and the orchestrator will exclude them.
- AniList state persistence filters “ignored” non-anime matches to avoid polluting
state.jsonand repeated re-resolve attempts.
🔧 Fixes & Changes
- Fixed: Metadata lookups no longer misclassify anime as movies (anime is treated as show-type internally for sync logic).
- Fixed: Anime ratings and watchlist items are no longer skipped when filters are enabled.
- Fixed: Plex watcher and webhook ratings “clear stars” (unrate) now sends a proper ratings remove/0.
- Changed: In insight overview we already had M for Movies, S for Shows and now also A for Anime
- Changed: Analyzed and Editor includes Anime types and AniList is added to the list.
- Improved: Unresolved-item reporting now shows better keys for anime items.
CrossWatch - v0.6.1
🔧 Fixes & Changes
- Fixed: Importing SIMKL History from the Editor no longer creates lots of “Unknown” entries (movies and episodes now import with proper IDs).
- Fixed: SIMKL History episode imports now keep real episode titles instead of falling back to generic
S01E01style names. - Fixed: Plex watcher Live scrobble progress is now accurate even when multiple Plex users watch the same movie/show at the same time.
- Fixed: Plex webhook scrobble progress is now accurate even when multiple Plex users watch the same movie/show at the same time.
- Fixed: MDBList cleanup tool in /scripts/ - pagination now works reliably and stops correctly at the end.
- Fixed: MDBList episode ratings now store the real episode title in
state.json - Improved: SIMKL History imports are more reliable overall thanks to better handling of SIMKL’s nested data format (the Editor now reads what SIMKL actually sends).
CrossWatch - v0.6.0
Happy 2026. v0.6.0 is mainly about ratings: most provider modules were reworked to behave sanely in true two-way setups.
Big win: Plex ratings are now dramatically faster thanks to query changes (in some libraries, up to ~50×).
As with any feature release, it’s a good idea to run Maintenance to clean up your environment.
If you’re still using a config.json from older versions (< 0.5.x), you should think about rebuilding a fresh, clean config.json.
As with any feature release, expect a few bugs, don’t be surprised.
🔧 Fixes & Improvements
Orchestrator
- Two-way ratings: improved planning and execution for bidirectional ratings sync.
- Disabled pairs: disabled pairs no longer trigger snapshots (cleaner logs).
Ratings
- Plex: major query optimization (can be ~50× faster in some cases).
- Plex: improved ID resolving and lookups.
- Trakt: better season/episode ID resolving.
- SIMKL: better show/movie ID resolving.
- MDBList: fixed pagination behavior (no more “needs multiple sync runs to finish”).
Watcher & Webhooks
- Trakt sink: no more duplicate history entries
- Fixed a rare legacy-config edge case causing two “finish” events for the same playback.
- Improved duplicate-stop suppression for stop/resume/credit-skip edge cases.
- Plex ratings: fixed ratings processing in both Plex Webhook and Plex Watcher.
- Quick stops now actually stop
- Fixed debounce issues where very short sessions could miss the final stop event.
- Trakt and SIMKL scrobble state now ends cleanly even if you stop within a few seconds.
- Jellyfin webhook reliability
- Stronger protection against double “finish” events.
- More consistent stop handling during frequent progress updates.
Analyzer
- Pair-scope awareness: analyzer now respects per-pair feature scope (such as
ratings.types: ["movies","shows"]). - Out-of-scope summary: when everything is “All good”, the analyzer can still show what’s excluded by configuration
(example: “X seasons / Y episodes not synced due to pair setup”), so you don’t go hunting ghosts.
Other
- SIMKL Watchlist: added some caching improvements.
- SIMKL History: episodes now include episode titles.
- Editor: UI tweaks - season and episode shown next to TV shows.
CrossWatch - v0.5.8
This release add ratings for Plex webhook/watcher and fixes a long-standing Plex annoyance: PIN-protected Plex Home users.
CrossWatch can now switch into the correct Plex user context (even when that user has a PIN).
NOTE: This is ONLY needed for the default enabled Marked Watched plex option (manual “Mark as Watched” actions in the Plex UI).
Ratings are now supported for Plex Webhooks and Plex Watcher. CrossWatch will forward your ratings to Trakt and/or SIMKL.
updated WIKI pages:
PLEX Module
Webhook
Watcher
✨ Highlights
- Ratings for Plex Webhook and Plex Watcher are now supported
- You can now include ratings; enable it in Webhook options or Watcher options.
- For Watcher, you need to add a webhook helper, so Plex Pass is required for this option to work.
- Plex Marked Watched enhancements
- This option fetches items you manually marked as watched in Plex. Default: enabled.
- Previously it only worked reliably for the Plex Owner; Home users (with or without PINs) were not handled correctly.
🔧 Fixes & Improvements
- Correct Plex user context
- CrossWatch now attempts to switch to the configured Plex user before syncing user-specific data.
- If the user is PIN-protected, the PIN is used during the switch.
- If switching isn’t possible (wrong/missing PIN, not a Home user, etc.), CrossWatch falls back to the token user and logs why.
- If CrossWatch cannot switch to the intended user, it disables marked watched to avoid syncing the wrong profile.
- Trakt ratings
- Added retries and backoff, including
Retry-Aftersupport. - Canonical keys for seasons/episodes: cache merge/remove now includes
show_ids+ season/episode identifiers. - Improved debug logging: status codes and short response bodies on failures.
- Added retries and backoff, including
I’d love to add ratings for Emby and Jellyfin, just like Plex. The problem is: I can’t find any UI option to set user-specific ratings in Emby/Jellyfin.
Maybe I’m just blind. I do see rating-related fields in their APIs, but I’m not seeing the equivalent in the UI. Since I’m not an Emby or Jellyfin user, I might be missing something.
If you know where user ratings live in the UI (or if I’m wrong about how it works), please drop a note in the discussion so I can take another look.
CrossWatch - v0.5.7
BEST WISHES FOR 2026
This release adds Scrobble Library Whitelisting for Plex, Emby, and Jellyfin.
You can now choose exactly which libraries are allowed to generate scrobbles (Simkl/Trakt, etc.).
Configure it under settings - authentication - Plex/Emby/Jellyfin - settings.. Look for the Kermit-the-Frog green dots, that’s Scrobble.
If the scrobble whitelist is empty, CrossWatch will scrobble everything (current behavior).
This applies to both Scrobble input paths (watchers and webhooks):
- Watchers (local polling/stream watchers)
- Webhooks (server push events)
READ the WIKI regarding whitelisting
✨ Highlights
- Scrobble Library Whitelisting (Plex / Emby / Jellyfin)
- Empty whitelist = allow all (no filtering)
- New S (Scrobble) column next to H (History) and R (Ratings) in provider settings
- Emby/Jellyfin use “virtual” views, so CrossWatch resolves the correct View before applying the whitelist
- Prevents scrobbles leaking from non-whitelisted libraries
CrossWatch - v0.5.6
This release adds a new provider: Tautulli.
Tautulli is a Plex monitoring and analytics tool and NOT a tracker or media server, so CrossWatch uses it only to import your existing Plex watch history
DO NOT pair Tautulli as a destination (or “sync into” anything). It’s not a tracker/media server and will generate garbage matches: wrong IDs, tons of false items, and a bad time. Use it as a source-only helper and NEVER as a direct sync target to Plex, Jellyfin, Trakt, SIMKL, or anything else. The only correct use case: Either import the Tautulli dataset directly into the Editor, or create a one-way sync pair from Tautulli to CrossWatch Tracker.
If this all doesn’t ring a bell, you probably don’t need Tautulli imports, it’s only for a specific group of long-time Plex users with lots of existing history in Tautulli.
READ the WIKI
✨ Highlights
- New provider: Tautulli (History Import only)
- Import your historical watches from Tautulli into CrossWatch
- Tautulli is source-only: it can’t be selected as a destination
- When using Tautulli, sync is one-way only
CrossWatch - v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch - v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch - v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch - v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch - v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch - v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Run Settings → Maintenance and perform a full cleanup after upgrading to v0.5.0.
- Remove any Jellyfin pairs that included ratings, then recreate them without rating sync.
- Optional: delete config.json for a clean start.
- Jellyfin ratings sync feature removed (disabled by default).
Full changelog
CrossWatch - v0.6.1
🔧 Fixes & Changes
- Fixed: Importing SIMKL History from the Editor no longer creates lots of “Unknown” entries (movies and episodes now import with proper IDs).
- Fixed: SIMKL History episode imports now keep real episode titles instead of falling back to generic
S01E01style names. - Fixed: Plex watcher Live scrobble progress is now accurate even when multiple Plex users watch the same movie/show at the same time.
- Fixed: Plex webhook scrobble progress is now accurate even when multiple Plex users watch the same movie/show at the same time.
- Fixed: MDBList cleanup tool in /scripts/ - pagination now works reliably and stops correctly at the end.
- Fixed: MDBList episode ratings now store the real episode title in
state.json - Improved: SIMKL History imports are more reliable overall thanks to better handling of SIMKL’s nested data format (the Editor now reads what SIMKL actually sends).
CrossWatch - v0.6.0
Happy 2026. v0.6.0 is mainly about ratings: most provider modules were reworked to behave sanely in true two-way setups.
Big win: Plex ratings are now dramatically faster thanks to query changes (in some libraries, up to ~50×).
As with any feature release, it’s a good idea to run Maintenance to clean up your environment.
If you’re still using a config.json from older versions (< 0.5.x), you should think about rebuilding a fresh, clean config.json.
As with any feature release, expect a few bugs, don’t be surprised.
🔧 Fixes & Improvements
Orchestrator
- Two-way ratings: improved planning and execution for bidirectional ratings sync.
- Disabled pairs: disabled pairs no longer trigger snapshots (cleaner logs).
Ratings
- Plex: major query optimization (can be ~50× faster in some cases).
- Plex: improved ID resolving and lookups.
- Trakt: better season/episode ID resolving.
- SIMKL: better show/movie ID resolving.
- MDBList: fixed pagination behavior (no more “needs multiple sync runs to finish”).
Watcher & Webhooks
- Trakt sink: no more duplicate history entries
- Fixed a rare legacy-config edge case causing two “finish” events for the same playback.
- Improved duplicate-stop suppression for stop/resume/credit-skip edge cases.
- Plex ratings: fixed ratings processing in both Plex Webhook and Plex Watcher.
- Quick stops now actually stop
- Fixed debounce issues where very short sessions could miss the final stop event.
- Trakt and SIMKL scrobble state now ends cleanly even if you stop within a few seconds.
- Jellyfin webhook reliability
- Stronger protection against double “finish” events.
- More consistent stop handling during frequent progress updates.
Analyzer
- Pair-scope awareness: analyzer now respects per-pair feature scope (such as
ratings.types: ["movies","shows"]). - Out-of-scope summary: when everything is “All good”, the analyzer can still show what’s excluded by configuration
(example: “X seasons / Y episodes not synced due to pair setup”), so you don’t go hunting ghosts.
Other
- SIMKL Watchlist: added some caching improvements.
- SIMKL History: episodes now include episode titles.
- Editor: UI tweaks - season and episode shown next to TV shows.
CrossWatch - v0.5.8
This release add ratings for Plex webhook/watcher and fixes a long-standing Plex annoyance: PIN-protected Plex Home users.
CrossWatch can now switch into the correct Plex user context (even when that user has a PIN).
NOTE: This is ONLY needed for the default enabled Marked Watched plex option (manual “Mark as Watched” actions in the Plex UI).
Ratings are now supported for Plex Webhooks and Plex Watcher. CrossWatch will forward your ratings to Trakt and/or SIMKL.
updated WIKI pages:
PLEX Module
Webhook
Watcher
✨ Highlights
- Ratings for Plex Webhook and Plex Watcher are now supported
- You can now include ratings; enable it in Webhook options or Watcher options.
- For Watcher, you need to add a webhook helper, so Plex Pass is required for this option to work.
- Plex Marked Watched enhancements
- This option fetches items you manually marked as watched in Plex. Default: enabled.
- Previously it only worked reliably for the Plex Owner; Home users (with or without PINs) were not handled correctly.
🔧 Fixes & Improvements
- Correct Plex user context
- CrossWatch now attempts to switch to the configured Plex user before syncing user-specific data.
- If the user is PIN-protected, the PIN is used during the switch.
- If switching isn’t possible (wrong/missing PIN, not a Home user, etc.), CrossWatch falls back to the token user and logs why.
- If CrossWatch cannot switch to the intended user, it disables marked watched to avoid syncing the wrong profile.
- Trakt ratings
- Added retries and backoff, including
Retry-Aftersupport. - Canonical keys for seasons/episodes: cache merge/remove now includes
show_ids+ season/episode identifiers. - Improved debug logging: status codes and short response bodies on failures.
- Added retries and backoff, including
I’d love to add ratings for Emby and Jellyfin, just like Plex. The problem is: I can’t find any UI option to set user-specific ratings in Emby/Jellyfin.
Maybe I’m just blind. I do see rating-related fields in their APIs, but I’m not seeing the equivalent in the UI. Since I’m not an Emby or Jellyfin user, I might be missing something.
If you know where user ratings live in the UI (or if I’m wrong about how it works), please drop a note in the discussion so I can take another look.
CrossWatch - v0.5.7
BEST WISHES FOR 2026
This release adds Scrobble Library Whitelisting for Plex, Emby, and Jellyfin.
You can now choose exactly which libraries are allowed to generate scrobbles (Simkl/Trakt, etc.).
Configure it under settings - authentication - Plex/Emby/Jellyfin - settings.. Look for the Kermit-the-Frog green dots, that’s Scrobble.
If the scrobble whitelist is empty, CrossWatch will scrobble everything (current behavior).
This applies to both Scrobble input paths (watchers and webhooks):
- Watchers (local polling/stream watchers)
- Webhooks (server push events)
READ the WIKI regarding whitelisting
✨ Highlights
- Scrobble Library Whitelisting (Plex / Emby / Jellyfin)
- Empty whitelist = allow all (no filtering)
- New S (Scrobble) column next to H (History) and R (Ratings) in provider settings
- Emby/Jellyfin use “virtual” views, so CrossWatch resolves the correct View before applying the whitelist
- Prevents scrobbles leaking from non-whitelisted libraries
CrossWatch - v0.5.6
This release adds a new provider: Tautulli.
Tautulli is a Plex monitoring and analytics tool and NOT a tracker or media server, so CrossWatch uses it only to import your existing Plex watch history
DO NOT pair Tautulli as a destination (or “sync into” anything). It’s not a tracker/media server and will generate garbage matches: wrong IDs, tons of false items, and a bad time. Use it as a source-only helper and NEVER as a direct sync target to Plex, Jellyfin, Trakt, SIMKL, or anything else. The only correct use case: Either import the Tautulli dataset directly into the Editor, or create a one-way sync pair from Tautulli to CrossWatch Tracker.
If this all doesn’t ring a bell, you probably don’t need Tautulli imports, it’s only for a specific group of long-time Plex users with lots of existing history in Tautulli.
READ the WIKI
✨ Highlights
- New provider: Tautulli (History Import only)
- Import your historical watches from Tautulli into CrossWatch
- Tautulli is source-only: it can’t be selected as a destination
- When using Tautulli, sync is one-way only
CrossWatch - v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch - v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch - v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch - v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch - v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch - v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Run Maintenance → Delete Everything / Clean Everything after upgrade to rebuild state/caches.
- Remove and re‑create any CrossWatch pairs that included Jellyfin ratings, then restart the application.
- Disabled Jellyfin ratings sync; feature removed until reliable implementation is added.
Full changelog
CrossWatch - v0.6.0
Happy 2026. v0.6.0 is mainly about ratings: most provider modules were reworked to behave sanely in true two-way setups.
Big win: Plex ratings are now dramatically faster thanks to query changes (in some libraries, up to ~50×).
As with any feature release, it’s a good idea to run Maintenance to clean up your environment.
If you’re still using a config.json from older versions (< 0.5.x), you should think about rebuilding a fresh, clean config.json.
As with any feature release, expect a few bugs, don’t be surprised.
🔧 Fixes & Improvements
Orchestrator
- Two-way ratings: improved planning and execution for bidirectional ratings sync.
- Disabled pairs: disabled pairs no longer trigger snapshots (cleaner logs).
Ratings
- Plex: major query optimization (can be ~50× faster in some cases).
- Plex: improved ID resolving and lookups.
- Trakt: better season/episode ID resolving.
- SIMKL: better show/movie ID resolving.
- MDBList: fixed pagination behavior (no more “needs multiple sync runs to finish”).
Watcher & Webhooks
- Trakt sink: no more duplicate history entries
- Fixed a rare legacy-config edge case causing two “finish” events for the same playback.
- Improved duplicate-stop suppression for stop/resume/credit-skip edge cases.
- Plex ratings: fixed ratings processing in both Plex Webhook and Plex Watcher.
- Quick stops now actually stop
- Fixed debounce issues where very short sessions could miss the final stop event.
- Trakt and SIMKL scrobble state now ends cleanly even if you stop within a few seconds.
- Jellyfin webhook reliability
- Stronger protection against double “finish” events.
- More consistent stop handling during frequent progress updates.
Analyzer
- Pair-scope awareness: analyzer now respects per-pair feature scope (such as
ratings.types: ["movies","shows"]). - Out-of-scope summary: when everything is “All good”, the analyzer can still show what’s excluded by configuration
(example: “X seasons / Y episodes not synced due to pair setup”), so you don’t go hunting ghosts.
Other
- SIMKL Watchlist: added some caching improvements.
- SIMKL History: episodes now include episode titles.
- Editor: UI tweaks - season and episode shown next to TV shows.
CrossWatch - v0.5.8
This release add ratings for Plex webhook/watcher and fixes a long-standing Plex annoyance: PIN-protected Plex Home users.
CrossWatch can now switch into the correct Plex user context (even when that user has a PIN).
NOTE: This is ONLY needed for the default enabled Marked Watched plex option (manual “Mark as Watched” actions in the Plex UI).
Ratings are now supported for Plex Webhooks and Plex Watcher. CrossWatch will forward your ratings to Trakt and/or SIMKL.
updated WIKI pages:
PLEX Module
Webhook
Watcher
✨ Highlights
- Ratings for Plex Webhook and Plex Watcher are now supported
- You can now include ratings; enable it in Webhook options or Watcher options.
- For Watcher, you need to add a webhook helper, so Plex Pass is required for this option to work.
- Plex Marked Watched enhancements
- This option fetches items you manually marked as watched in Plex. Default: enabled.
- Previously it only worked reliably for the Plex Owner; Home users (with or without PINs) were not handled correctly.
🔧 Fixes & Improvements
- Correct Plex user context
- CrossWatch now attempts to switch to the configured Plex user before syncing user-specific data.
- If the user is PIN-protected, the PIN is used during the switch.
- If switching isn’t possible (wrong/missing PIN, not a Home user, etc.), CrossWatch falls back to the token user and logs why.
- If CrossWatch cannot switch to the intended user, it disables marked watched to avoid syncing the wrong profile.
- Trakt ratings
- Added retries and backoff, including
Retry-Aftersupport. - Canonical keys for seasons/episodes: cache merge/remove now includes
show_ids+ season/episode identifiers. - Improved debug logging: status codes and short response bodies on failures.
- Added retries and backoff, including
I’d love to add ratings for Emby and Jellyfin, just like Plex. The problem is: I can’t find any UI option to set user-specific ratings in Emby/Jellyfin.
Maybe I’m just blind. I do see rating-related fields in their APIs, but I’m not seeing the equivalent in the UI. Since I’m not an Emby or Jellyfin user, I might be missing something.
If you know where user ratings live in the UI (or if I’m wrong about how it works), please drop a note in the discussion so I can take another look.
CrossWatch - v0.5.7
BEST WISHES FOR 2026
This release adds Scrobble Library Whitelisting for Plex, Emby, and Jellyfin.
You can now choose exactly which libraries are allowed to generate scrobbles (Simkl/Trakt, etc.).
Configure it under settings - authentication - Plex/Emby/Jellyfin - settings.. Look for the Kermit-the-Frog green dots, that’s Scrobble.
If the scrobble whitelist is empty, CrossWatch will scrobble everything (current behavior).
This applies to both Scrobble input paths (watchers and webhooks):
- Watchers (local polling/stream watchers)
- Webhooks (server push events)
READ the WIKI regarding whitelisting
✨ Highlights
- Scrobble Library Whitelisting (Plex / Emby / Jellyfin)
- Empty whitelist = allow all (no filtering)
- New S (Scrobble) column next to H (History) and R (Ratings) in provider settings
- Emby/Jellyfin use “virtual” views, so CrossWatch resolves the correct View before applying the whitelist
- Prevents scrobbles leaking from non-whitelisted libraries
CrossWatch - v0.5.6
This release adds a new provider: Tautulli.
Tautulli is a Plex monitoring and analytics tool and NOT a tracker or media server, so CrossWatch uses it only to import your existing Plex watch history
DO NOT pair Tautulli as a destination (or “sync into” anything). It’s not a tracker/media server and will generate garbage matches: wrong IDs, tons of false items, and a bad time. Use it as a source-only helper and NEVER as a direct sync target to Plex, Jellyfin, Trakt, SIMKL, or anything else. The only correct use case: Either import the Tautulli dataset directly into the Editor, or create a one-way sync pair from Tautulli to CrossWatch Tracker.
If this all doesn’t ring a bell, you probably don’t need Tautulli imports, it’s only for a specific group of long-time Plex users with lots of existing history in Tautulli.
READ the WIKI
✨ Highlights
- New provider: Tautulli (History Import only)
- Import your historical watches from Tautulli into CrossWatch
- Tautulli is source-only: it can’t be selected as a destination
- When using Tautulli, sync is one-way only
CrossWatch - v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch - v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch - v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch - v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch - v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch - v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Ratings for Plex Webhook and Watcher are now supported; can be enabled in options and forwarded to Trakt and/or SIMKL.
Full changelog
CrossWatch - v0.5.8
This release add ratings for Plex webhook/watcher and fixes a long-standing Plex annoyance: PIN-protected Plex Home users.
CrossWatch can now switch into the correct Plex user context (even when that user has a PIN).
NOTE: This is ONLY needed for the default enabled Marked Watched plex option (manual “Mark as Watched” actions in the Plex UI).
Ratings are now supported for Plex Webhooks and Plex Watcher. CrossWatch will forward your ratings to Trakt and/or SIMKL.
updated WIKI pages:
PLEX Module
Webhook
Watcher
✨ Highlights
- Ratings for Plex Webhook and Plex Watcher are now supported
- You can now include ratings; enable it in Webhook options or Watcher options.
- For Watcher, you need to add a webhook helper, so Plex Pass is required for this option to work.
- Plex Marked Watched enhancements
- This option fetches items you manually marked as watched in Plex. Default: enabled.
- Previously it only worked reliably for the Plex Owner; Home users (with or without PINs) were not handled correctly.
🔧 Fixes & Improvements
- Correct Plex user context
- CrossWatch now attempts to switch to the configured Plex user before syncing user-specific data.
- If the user is PIN-protected, the PIN is used during the switch.
- If switching isn’t possible (wrong/missing PIN, not a Home user, etc.), CrossWatch falls back to the token user and logs why.
- If CrossWatch cannot switch to the intended user, it disables marked watched to avoid syncing the wrong profile.
- Trakt ratings
- Added retries and backoff, including
Retry-Aftersupport. - Canonical keys for seasons/episodes: cache merge/remove now includes
show_ids+ season/episode identifiers. - Improved debug logging: status codes and short response bodies on failures.
- Added retries and backoff, including
I’d love to add ratings for Emby and Jellyfin, just like Plex. The problem is: I can’t find any UI option to set user-specific ratings in Emby/Jellyfin.
Maybe I’m just blind. I do see rating-related fields in their APIs, but I’m not seeing the equivalent in the UI. Since I’m not an Emby or Jellyfin user, I might be missing something.
If you know where user ratings live in the UI (or if I’m wrong about how it works), please drop a note in the discussion so I can take another look.
CrossWatch - v0.5.7
BEST WISHES FOR 2026
This release adds Scrobble Library Whitelisting for Plex, Emby, and Jellyfin.
You can now choose exactly which libraries are allowed to generate scrobbles (Simkl/Trakt, etc.).
Configure it under settings - authentication - Plex/Emby/Jellyfin - settings.. Look for the Kermit-the-Frog green dots, that’s Scrobble.
If the scrobble whitelist is empty, CrossWatch will scrobble everything (current behavior).
This applies to both Scrobble input paths (watchers and webhooks):
- Watchers (local polling/stream watchers)
- Webhooks (server push events)
READ the WIKI regarding whitelisting
✨ Highlights
- Scrobble Library Whitelisting (Plex / Emby / Jellyfin)
- Empty whitelist = allow all (no filtering)
- New S (Scrobble) column next to H (History) and R (Ratings) in provider settings
- Emby/Jellyfin use “virtual” views, so CrossWatch resolves the correct View before applying the whitelist
- Prevents scrobbles leaking from non-whitelisted libraries
CrossWatch - v0.5.6
This release adds a new provider: Tautulli.
Tautulli is a Plex monitoring and analytics tool and NOT a tracker or media server, so CrossWatch uses it only to import your existing Plex watch history
DO NOT pair Tautulli as a destination (or “sync into” anything). It’s not a tracker/media server and will generate garbage matches: wrong IDs, tons of false items, and a bad time. Use it as a source-only helper and NEVER as a direct sync target to Plex, Jellyfin, Trakt, SIMKL, or anything else. The only correct use case: Either import the Tautulli dataset directly into the Editor, or create a one-way sync pair from Tautulli to CrossWatch Tracker.
If this all doesn’t ring a bell, you probably don’t need Tautulli imports, it’s only for a specific group of long-time Plex users with lots of existing history in Tautulli.
READ the WIKI
✨ Highlights
- New provider: Tautulli (History Import only)
- Import your historical watches from Tautulli into CrossWatch
- Tautulli is source-only: it can’t be selected as a destination
- When using Tautulli, sync is one-way only
CrossWatch - v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch - v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch - v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch - v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch - v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch - v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Scrobble Library Whitelisting for Plex, Emby, and Jellyfin with S column indicator
- Empty whitelist retains current behavior of scrobbling everything
Full changelog
CrossWatch - v0.5.7
BEST WISHES FOR 2026
This release adds Scrobble Library Whitelisting for Plex, Emby, and Jellyfin.
You can now choose exactly which libraries are allowed to generate scrobbles (Simkl/Trakt, etc.).
Configure it under settings - authentication - Plex/Emby/Jellyfin - settings.. Look for the Kermit-the-Frog green dots, that’s Scrobble.
If the scrobble whitelist is empty, CrossWatch will scrobble everything (current behavior).
This applies to both Scrobble input paths (watchers and webhooks):
- Watchers (local polling/stream watchers)
- Webhooks (server push events)
READ the WIKI regarding whitelisting
✨ Highlights
- Scrobble Library Whitelisting (Plex / Emby / Jellyfin)
- Empty whitelist = allow all (no filtering)
- New S (Scrobble) column next to H (History) and R (Ratings) in provider settings
- Emby/Jellyfin use “virtual” views, so CrossWatch resolves the correct View before applying the whitelist
- Prevents scrobbles leaking from non-whitelisted libraries
CrossWatch - v0.5.6
This release adds a new provider: Tautulli.
Tautulli is a Plex monitoring and analytics tool and NOT a tracker or media server, so CrossWatch uses it only to import your existing Plex watch history
DO NOT pair Tautulli as a destination (or “sync into” anything). It’s not a tracker/media server and will generate garbage matches: wrong IDs, tons of false items, and a bad time. Use it as a source-only helper and NEVER as a direct sync target to Plex, Jellyfin, Trakt, SIMKL, or anything else. The only correct use case: Either import the Tautulli dataset directly into the Editor, or create a one-way sync pair from Tautulli to CrossWatch Tracker.
If this all doesn’t ring a bell, you probably don’t need Tautulli imports, it’s only for a specific group of long-time Plex users with lots of existing history in Tautulli.
READ the WIKI
✨ Highlights
- New provider: Tautulli (History Import only)
- Import your historical watches from Tautulli into CrossWatch
- Tautulli is source-only: it can’t be selected as a destination
- When using Tautulli, sync is one-way only
CrossWatch - v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch - v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch - v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch - v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch - v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch - v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Run Settings → Maintenance → Delete Everything / Clean Everything after upgrade to rebuild caches.
- Re‑create any Jellyfin pairs that included rating synchronization.
- Disabled Jellyfin ratings sync – previously enabled functionality is now removed.
Full changelog
CrossWatch – v0.5.6
This release adds a new provider: Tautulli.
Tautulli is a Plex monitoring and analytics tool and NOT a tracker or media server, so CrossWatch uses it only to import your existing Plex watch history
DO NOT pair Tautulli as a destination (or “sync into” anything). It’s not a tracker/media server and will generate garbage matches: wrong IDs, tons of false items, and a bad time. Use it as a source-only helper and NEVER as a direct sync target to Plex, Jellyfin, Trakt, SIMKL, or anything else. The only correct use case: Either import the Tautulli dataset directly into the Editor, or create a one-way sync pair from Tautulli to CrossWatch Tracker.
If this all doesn’t ring a bell, you probably don’t need Tautulli imports, it’s only for a specific group of long-time Plex users with lots of existing history in Tautulli.
READ the WIKI
✨ Highlights
- New provider: Tautulli (History Import only)
- Import your historical watches from Tautulli into CrossWatch
- Tautulli is source-only: it can’t be selected as a destination
- When using Tautulli, sync is one-way only
CrossWatch – v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch – v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch – v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch – v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch – v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch – v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Removed the autoplay quarantine logic for Plex webhooks (now obsolete due to Plex bug fixes).
Full changelog
CrossWatch – v0.5.5
This update focuses on making Plex to Trakt scrobbling (webhook mode) behave a litte bit better.
Plex fixed some webhook autoplay bugs where a new scrobble start was never sent.
The CW Plex webhook logic now matches Plex’s updated behavior, and the old quarantine/autoplay workaround has been removed.
🔧 Fixes & Improvements
- Plex Webhook (Plex to Trakt scrobble)
- Removed the autoplay quarantine logic that was meant to detect autoplay episodes. Obsolute due to Plex bug fixes.
- Scrobble state is now tied more strongly to the correct user and playback session, reducing mix-ups in multi-user setups.
- Better handling of Plex progress weirdness (including the classic “pause at 100%”).
- Smarter decisions on whether an event should be treated as pause or stop, keeping Trakt history cleaner.
- Stronger fallback logic for resolving episode/show IDs when Plex metadata is incomplete, improving Trakt matching for TV episodes.
CrossWatch – v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch – v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch – v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch – v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch – v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Run Settings → Maintenance → Delete Everything / Clean Everything after upgrading from pre‑0.5.0 versions, then reopen CrossWatch.
- Remove and re‑create any Jellyfin pairs that included ratings due to the disablement of Jellyfin ratings sync.
- Metadata localization (TMDB) supporting language codes via Settings -> Metadata providers -> TMDB -> Advanced
- Improved Editor: dual data sources (CW Tracker and Current State with provider/feature selector and item blocking)
- Item blocking in Current State using the trashbin button; changes saved to /config/state.manual.json
Full changelog
CrossWatch – v0.5.4
Another small but important update, and the last one of the year. Wishing you all a great time.
This one is again editor-focused. If you don’t see the changes, do a hard refresh / clear your browser cache (yes, again).
You can now populate state.json without setting up a sync pair first, a huge improvement.
Read all about the new import datasets function here
🔧 Fixes & Improvements
- Editor upgrades – Import datasets
- Import your datasets from Plex, Trakt, etc. (Watchlist / History / Ratings) so you can edit/block items before running any sync.
- Changed: MetaAPI now uses an absolute path, improving compatibility with some reverse proxies.
CrossWatch – v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- Editor upgrades
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch – v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch – v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch – v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Per‑provider blocking of movies, shows, or episodes in the CW Orchestrator (experimental)
- Metadata localization via TMDB with language selection in Settings
Full changelog
CrossWatch – v0.5.3
A small update for improved editing. Please refresh/clean your browser cache if you dont see the changes in editor.
🔧 Fixes & Improvements
- ** Editor upgrades**
- Bulk selection (select page / multi-select) with bulk delete/restore.
- Type filters (Movie / Show / Season / Episode) and a Blocked-only view (Current State).
CrossWatch – v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch – v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch – v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Run Settings → Maintenance → Delete Everything / Clean Everything and restart CrossWatch after upgrading to v0.5.0.
- Re‑create any Jellyfin pairs that included ratings.
- Disabled Jellyfin ratings sync (feature removed in v0.5.0).
Full changelog
CrossWatch – v0.5.2
Some small fixes.
🔧 Fixes & Changes
- Fallback GUID: works again (Plex only option). In 0.5.0 the index was cleaned before the fallback GUIDs were merged. Now fixed again. Note: use this as a one-time sync, then disable it.
- Plex changes: fallback has been removed so usernames and user IDs are honored again.
CrossWatch – v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch – v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Run Delete Everything / Clean Everything from Settings → Maintenance after upgrade to rebuild fresh state/caches.
- Recreate any Jellyfin pairs that included ratings.
- Metadata localization for TMDB descriptions via Settings -> Metadata providers -> TMDB -> Advanced
- Improved Editor supporting CW Tracker and Current State with per‑provider item blocking
Full changelog
CrossWatch – v0.5.1
Some small updates and quality-of-life improvements. And one big update.
One long-standing irritation by me was that there was no simple way to say: “do not sync this movie, show, or episode”.
If a provider kept reporting it, CrossWatch would keep planning it. That ends now: you can block items per provider so they won’t be pushed out to targets.
Blocking happens at the highest level: the CW Orchestrator. This function is still experimental...
And like with all my updates: hit Save in Settings at least once, so any new/changed config variables get written into your config.json.
✨ Highlights
- Metadata localization (TMDB): descriptions can now show in your own language (when available)
, Default isen-US
, Change it in Settings -> Metadata providers -> TMDB -> Advanced
I've updated the WIKI Metadata with all possible localizatin codes here.
- Improved Editor: the editor now supports two different data sources
- CW Tracker (the existing CW tracker editing and snapshots)
-Current State (/config/state.json) with a Provider and Feature selector
-In Current State, you can block items per provider so they won’t sync out to targets. - The trashbin button will block them, and if you want to unblock them just push the same trashbin button again.
- Your Current State changes are saved separately (
/config/state.manual.json) and will NOT be deleted automatically.
- CW Tracker (the existing CW tracker editing and snapshots)
I've updated the WIKI Editor page here
🔧 Fixes & Changes
- Changed: absolute path is used for watchlist, to be compatible with some reverse proxies
- Changed: watcher sink adjustments apply immediately, no container restart needed
- Fixed: deleting an item in watchlist for CW TRacker, now actually deletes it
- Fixed: watchlist posters more often include titles on the cover
CrossWatch – v0.5.0
Welcome at version 0.5.0 as stated before this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
- Jellyfin ratings sync is disabled (removed functionality).
- Full cleanup required: run Delete Everything / Clean Everything in Settings → Maintenance before upgrading.
Full changelog
CrossWatch – v0.5.0
Welcome at version 0.5.0...and as stated before, this release is all about Refactors, file moves, and code restructuring.
Not glamorous, but it stops the codebase from evolving into a dumpster fire.
There are so many things improved, fixed, and changed that I honestly lost track.
⚠️ Important
Because of the larger code changes, I strongly recommend doing a full cleanup:
- Go to Settings → Maintenance
- Run Delete Everything / Clean Everything
- Then re-open CrossWatch so it rebuilds fresh state/caches
- Remove any pairs with Jellyfin that included ratings! and Create them again.
- Optional: remove you config.json to start clean.
This avoids stale tracker data, cached metadata, and old snapshots getting in the way of the refactor.
🔧 Fixes & Changes
- Jellyfin ratings sync is disabled.
- I tried, but Jellyfin (and Emby) ratings behavior is… special.
- It wasn’t working reliably anyway, so it’s off until it’s properly understood and implemented.
- UI improvement added: M: Movies S: Shows in insight
- Overal UI improvements smaller probes, css changes etc etc...
- Watchlist changes:
- Removed the movie/show overlay when in list view.
- Added background for the overlay (same principle as the Playing card)
- Provider changes:
- SIMKL Improved shadowing (more reliable diffing + fewer “phantom repeats”).
- TRAKT changes:
- Improved ID resolving (fewer mismatches, fewer “unresolved” surprises).
- CW now better supports Free accounts with better handling when Trakt limits are reached.
- Console now shows: “Trakt account limit reached”
- Trakt probe now reports:
- free-tier and VIP limits (watchlist + collections)
- last limit-related error (so you can actually see what happened)
- Analyzer will tell you when limits has reached.
- MDBList Ratings handling improved (fewer retries/loops).
- Jellyfin and Emby Watchlist pagination fixed.
- Added three more provider shell tools in /scripts for MDBList / Trakt / SIMKL.
- Analyzer changes:
- Improved detection logic.
- Finds more issues and is better at pointing out why something didn’t sync.
- Help function: in pair configuration i've added some help icons with mouse-over information.
From 0.5.x onward I’ll continue with some refactoring for javascript and CSS
CrossWatch – v0.4.9
Plex tweaked their Discover API again...... which broke Watchlist pagination.
🔧 Fixes & Changes
- Fixed: Plex Watchlist sync now correctly loads all items again. Plex Discover was misreporting pagination, so only the first N items were synced;
CrossWatch now works around this using container paging.
CrossWatch – v0.4.8
This will be the last functional update for a while. Next up: code cleanup, restructuring, and prep for v0.5.0.
In this build the Now Playing card has been completely refreshed. The old tooltip-style “Now Playing” view is gone.
The new Playing card:
- Shows a proper progress bar
- Needs real-time progress updates (which webhooks normally do not provide)
Real-time progress is supported for:
- Jellyfin Webhook (make sure Playback Progress is enabled in your Jellyfin webhook)
- Emby and Plex Watcher
Other webhooks (Plex / Emby webhook) do not provide progression updates. That’s on them, not on me.
The Playing card will still render and update when events come in, just without real-time progress.
Don’t like any of this?
You can disable the new Playing card under Settings → UI.
✨ Highlights
-
New “Now Playing” card
- Shows the current movie/show with backdrop, title, and progress bar.
- Updates live from Plex, Emby and Jellyfin while you play, pause or stop.
-
Emby Watcher: now includes real-time progress just like Plex
- When you skip or fast-forward in Emby, the progress now updates much more accurately in the Now Playing card and on Trakt/SIMKL.
-
Improved Trakt matching for Emby & Jellyfin
- Better detection of the correct show + episode on Trakt, even with strange IDs.
🔧 Fixes & Changes
- Changed: Improved Jellyfin webhook to support real-time progress. Note: You need to enable Playback Progress in your webhook!
- Changed: Trakt ID lookups (movie/show/episode) are now cached, reducing Trakt API calls.
- Changed: Default scrobble guard behavior (pause debounce, autoplay protection) tuned for fewer accidental scrobbles.
CrossWatch – v0.4.7
Plex’s “Mark as watched” and its actual play history are two different signals.
Until now, CrossWatch played it safe and only trusted real play history, completely ignoring items that were just marked as watched.
Enough people ran into that limitation that it was time to fix it.
With this release, CrossWatch now understands both – real plays and “marked watched”.
If you prefer the old behavior, just turn off Marked Watched under Pair → Providers → Plex.
MOD_PLEX WIKI page has been updated. https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
✨ Highlights
- Plex “Marked Watched” support
- In Pair → Providers → Plex you’ll now see a new toggle next to Fallback GUID called Marked Watched default is enabled.
- When this is enabled, CrossWatch will also look at Plex’s library “watched” state, not just the play history.
- That means:
- If you marked items as watched in Plex (without real play history), CrossWatch can now pick those up and sync them out.
🔧 Fixes & Changes
-
Stricter timestamps (no fake dates)
- For both real history and “marked watched” entries, CrossWatch now only uses items that have a real timestamp from Plex.
- If Plex doesn’t give a timestamp, that item is simply ignored for history sync.
- We no longer invent “watched_at = now”
-
Important: “Marked Watched” is one-way (adds only, no remove)
- Enabling Marked Watched makes CrossWatch treat things as watched:
- If Plex says an item is watched (history or marked watched), CrossWatch will sync that as watched.
- But there is no unwatch sync:
- If you unmark something as watched in Plex, CrossWatch will not go and remove/undo that play. That's just too risky.
- This is deliberate. Plex doesn’t emit a clean event, and trying to guess removals is a great way to wipe people’s history by accident.
- Enabling Marked Watched makes CrossWatch treat things as watched:
CrossWatch – v0.4.6
Sorry....Previously, a small CSS blending issue caused the Editor layout to break if you opened the Watchlist first. This has now been fixed.
I didn’t want to keep you waiting, so here’s the second update for today.
✨ Highlights
- Metadata search for CW Editor
- New compact, neon-style “Search metadata” popup that shows small posters for each result.
- Picking a result now automatically fills TMDb, IMDb, and Trakt IDs where available.
- The Key column is filled for you in the format
imdb:tt1234567when an IMDb ID is known.
🔧 Fixes & Changes
- Fixed: Opening Watchlist before the Editor could mess up the Editor layout.
- The Editor now keeps its layout intact when switching between pages, no refresh needed.
- Improved: Trakt connection is more reliable.
- Expired Trakt logins are refreshed automatically more often, reducing “Trakt disconnected” errors.
CrossWatch – v0.4.5
CrossWatch v0.4.5 makes it much easier to inspect, clean up, and repair your tracker data when something looks off.
This release introduces the CrossWatch Tracker Editor, so you can browse, filter, and edit Watchlist / History / Ratings in a structured table instead of digging through raw files.
Read more: https://github.com/cenodude/CrossWatch/wiki/Editor
I’m parking feature work for a bit and focusing on bug fixes only, my ass needs a little break.
✨ Highlights
- CrossWatch Tracker Editor
- Dedicated editor for CW tracker Watchlist / History / Ratings with search, paging, and inline editing.
- Backup and Restore
🔧 Fixes & Changes
-
Fixed: Items from Trakt sometimes showed up as “Untitled” in the tracker/analyzer
- Episode history and ratings from Trakt now correctly display their show/episode titles.
-
Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- Added Remove metadata cache to wipe cached posters and metadata.
- Added Clean Everything button that runs all maintenance actions in one go.
-
Added: CW Tracker Editor
- Edit tracker data for Watchlist, History, and Ratings in a single table.
- Global search bar, paging controls, and column sorting for Key, Type, Title, and Extra.
- Per-type filter chips to quickly show only Movies, Shows, or Episodes.
- Side panel with live stats: total rows, visible rows, and counts for movies/shows/episodes.
- Backup and restore: The editor also includes simple import/export tools to move tracker data around or create backups.
-
Changed: Snapshot naming handling
- Snapshot dropdowns now show friendly labels like
2025-11-28 - 11:43instead of raw filenames. - Snapshot picker inside Insights only lists the 10 most recent snapshots per feature to avoid huge lists.
- “Latest” snapshot is always available as a quick option.
- Snapshot dropdowns now show friendly labels like
-
Improved: Watchlist
- Only providers that actually synced for the list are shown.
- The CrossWatch provider label is shortened to “CW” in List Insight for a cleaner layout.
- Limits the amount of rows and/or posters to 50 at a time.
CrossWatch – v0.4.4
Small version bump, big changes.
A mistake is easily made, one bad sync, one wrong setting, and things can get messy fast.
This release is all about the new CrossWatch Tracker A built-in snapshot provider that stores your Watchlist, History and Ratings locally and lets you restore them into your other services.
Future CW versions will push this further with an editor and more advanced tools, giving you even more control over your data.
✨ Highlights
- CrossWatch Tracker (internal snapshot provider) - experimental, meaning: expect bugs.
- New provider card: CROSSWATCH
- Can be used like any other provider in a pair:
- As target → backup/snapshot from providers into CrossWatch.
- As source → restore from CrossWatch back into those providers.
- Automatic snapshots
- When CrossWatch is used as a target, it can automatically create snapshots of its data before changes are applied.
- Snapshots are timestamped JSON files per feature.
- You control:
- Retention (days) – how long old snapshots are kept.
- Max snapshots per feature – hard cap per feature.
- Auto snapshot on/off – decide if a backup/snapshot is taken before each update.
- Quick snapshot switching from the dashboard
- In Dashboard → Insights, click the CrossWatch tile while on Watchlist, Ratings or History.
- A small picker opens where you can:
- Switch to any available snapshot for that feature.
- Or go back to Latest with one click.
Read here for more information about the new CrossWatch Tracker. https://github.com/cenodude/CrossWatch/wiki/mod_CROSSWATCH
🔧 Fixes & Changes
- Fixed: In Dashboard → Insights, large provider numbers now auto-scale so big counts no longer get cut off in the tiles.
- Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- All maintenance actions are now grouped in a single, compact dialog, with clear descriptions per action.
- Changed: The old “User Interface” section in Settings is now simply called Settings, and contains two groups: user interface and CrossWatch tracker.
- Changed: Insights; see which snapshot is active when using CrossWatch tracker.
- In Dashboard → Insights, the CrossWatch tile shows:
- For Latest (default) → a “Latest” label.
- For a specific snapshot → the snapshot date (e.g.
dd-month-yy). - Or use the snapshot switching in the dashboard.
- In Dashboard → Insights, the CrossWatch tile shows:
CrossWatch – v0.4.3
Small release with targeted UI polish and stability improvements.
🔧 Fixes & Changes
- Fixed: Jellyfin server availability is now actively probed, so the banner correctly switches to “down” when the server is unreachable.
- Fixed: Sync progress bar visuals have been tuned; progress flows smoother across phases and reliably reaches 100% when the task completes.
- Fixed: Dashboard lanes no longer flicker or reuse stale data; a no-op sync (0 changes) now correctly shows empty lanes.
- Changed: Dashboard spotlight items (Watchlist / Ratings / History) are now ordered newest-first instead of oldest-first.
- Changed: Each lane now includes a More chip that opens a modal with the last 25 items. Use the Analyzer for a full list.
- Changed: Probe caching is now more aggressive, reducing the number of outbound API calls.
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first: https://github.com/cenodude/CrossWatch/wiki/Best-Practices
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools: https://github.com/cenodude/CrossWatch/wiki/Appendix---Script-folderplex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
Smaller, more reliable, and they handle missing/unreachable servers without crashing. These are essentially my test scripts to clean up, back up, and restore Plex/Emby/Jellyfin states.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
CrossWatch v0.4.9 fixes Plex Watchlist pagination causing only the first 100 items to sync.
Full changelog
CrossWatch – v0.4.9
Plex tweaked their Discover API again...... which broke Watchlist pagination.
🔧 Fixes & Changes
- Fixed: Plex Watchlist sync now correctly loads all items again. Plex Discover was misreporting pagination, so only the first 100 items were synced; CrossWatch now works around this using container paging.
CrossWatch – v0.4.8
This will be the last functional update for a while. Next up: code cleanup, restructuring, and prep for v0.5.0.
I will still update new 0.4.x releases to fix bugs etc.
In this build the Now Playing card has been completely refreshed. The old tooltip-style “Now Playing” view is gone.
The new Playing card: shows the currently playing movie or show at the bottom of your screen, with backdrop, title, and a progress bar.
Real-time progress is supported for:
- Jellyfin Webhook (make sure Playback Progress is enabled in your Jellyfin webhook)
- Emby and Plex Watcher
Other webhooks (Plex / Emby webhook) do not provide progression updates. That’s on them, not on me.
The Playing card will still render and update when events come in, just without real-time progress.
Don’t like any of this?
You can disable the new Playing card under Settings → UI.
✨ Highlights
-
New “Now Playing” card
- Shows the current movie/show with backdrop, title, and progress bar.
- Updates live from Plex, Emby and Jellyfin while you play, pause or stop.
-
Emby Watcher: now includes real-time progress just like Plex
- When you skip or fast-forward in Emby, the progress now updates much more accurately in the Now Playing card and on Trakt/SIMKL.
-
Improved Trakt matching for Emby & Jellyfin
- Better detection of the correct show + episode on Trakt, even with strange IDs.
🔧 Fixes & Changes
- Changed: Improved Jellyfin webhook to support real-time progress. Note: You need to enable Playback Progress in your webhook!
- Changed: Trakt ID lookups (movie/show/episode) are now cached, reducing Trakt API calls.
- Changed: Default scrobble guard behavior (pause debounce, autoplay protection) tuned for fewer accidental scrobbles.
CrossWatch – v0.4.7
Plex’s “Mark as watched” and its actual play history are two different signals.
Until now, CrossWatch played it safe and only trusted real play history, completely ignoring items that were just marked as watched.
Enough people ran into that limitation that it was time to fix it.
With this release, CrossWatch now understands both – real plays and “marked watched”.
If you prefer the old behavior, just turn off Marked Watched under Pair → Providers → Plex.
MOD_PLEX WIKI page has been updated. https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
✨ Highlights
- Plex “Marked Watched” support
- In Pair → Providers → Plex you’ll now see a new toggle next to Fallback GUID called Marked Watched default is enabled.
- When this is enabled, CrossWatch will also look at Plex’s library “watched” state, not just the play history.
- That means:
- If you marked items as watched in Plex (without real play history), CrossWatch can now pick those up and sync them out.
🔧 Fixes & Changes
-
Stricter timestamps (no fake dates)
- For both real history and “marked watched” entries, CrossWatch now only uses items that have a real timestamp from Plex.
- If Plex doesn’t give a timestamp, that item is simply ignored for history sync.
- We no longer invent “watched_at = now”
-
Important: “Marked Watched” is one-way (adds only, no remove)
- Enabling Marked Watched makes CrossWatch treat things as watched:
- If Plex says an item is watched (history or marked watched), CrossWatch will sync that as watched.
- But there is no unwatch sync:
- If you unmark something as watched in Plex, CrossWatch will not go and remove/undo that play. That's just too risky.
- This is deliberate. Plex doesn’t emit a clean event, and trying to guess removals is a great way to wipe people’s history by accident.
- Enabling Marked Watched makes CrossWatch treat things as watched:
CrossWatch – v0.4.6
Sorry....Previously, a small CSS blending issue caused the Editor layout to break if you opened the Watchlist first. This has now been fixed.
I didn’t want to keep you waiting, so here’s the second update for today.
✨ Highlights
- Metadata search for CW Editor
- New compact, neon-style “Search metadata” popup that shows small posters for each result.
- Picking a result now automatically fills TMDb, IMDb, and Trakt IDs where available.
- The Key column is filled for you in the format
imdb:tt1234567when an IMDb ID is known.
🔧 Fixes & Changes
- Fixed: Opening Watchlist before the Editor could mess up the Editor layout.
- The Editor now keeps its layout intact when switching between pages, no refresh needed.
- Improved: Trakt connection is more reliable.
- Expired Trakt logins are refreshed automatically more often, reducing “Trakt disconnected” errors.
CrossWatch – v0.4.5
CrossWatch v0.4.5 makes it much easier to inspect, clean up, and repair your tracker data when something looks off.
This release introduces the CrossWatch Tracker Editor, so you can browse, filter, and edit Watchlist / History / Ratings in a structured table instead of digging through raw files.
Read more: https://github.com/cenodude/CrossWatch/wiki/Editor
I’m parking feature work for a bit and focusing on bug fixes only, my ass needs a little break.
✨ Highlights
- CrossWatch Tracker Editor
- Dedicated editor for CW tracker Watchlist / History / Ratings with search, paging, and inline editing.
- Backup and Restore
🔧 Fixes & Changes
-
Fixed: Items from Trakt sometimes showed up as “Untitled” in the tracker/analyzer
- Episode history and ratings from Trakt now correctly display their show/episode titles.
-
Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- Added Remove metadata cache to wipe cached posters and metadata.
- Added Clean Everything button that runs all maintenance actions in one go.
-
Added: CW Tracker Editor
- Edit tracker data for Watchlist, History, and Ratings in a single table.
- Global search bar, paging controls, and column sorting for Key, Type, Title, and Extra.
- Per-type filter chips to quickly show only Movies, Shows, or Episodes.
- Side panel with live stats: total rows, visible rows, and counts for movies/shows/episodes.
- Backup and restore: The editor also includes simple import/export tools to move tracker data around or create backups.
-
Changed: Snapshot naming handling
- Snapshot dropdowns now show friendly labels like
2025-11-28 - 11:43instead of raw filenames. - Snapshot picker inside Insights only lists the 10 most recent snapshots per feature to avoid huge lists.
- “Latest” snapshot is always available as a quick option.
- Snapshot dropdowns now show friendly labels like
-
Improved: Watchlist
- Only providers that actually synced for the list are shown.
- The CrossWatch provider label is shortened to “CW” in List Insight for a cleaner layout.
- Limits the amount of rows and/or posters to 50 at a time.
CrossWatch – v0.4.4
Small version bump, big changes.
A mistake is easily made, one bad sync, one wrong setting, and things can get messy fast.
This release is all about the new CrossWatch Tracker A built-in snapshot provider that stores your Watchlist, History and Ratings locally and lets you restore them into your other services.
Future CW versions will push this further with an editor and more advanced tools, giving you even more control over your data.
✨ Highlights
- CrossWatch Tracker (internal snapshot provider) - experimental, meaning: expect bugs.
- New provider card: CROSSWATCH
- Can be used like any other provider in a pair:
- As target → backup/snapshot from providers into CrossWatch.
- As source → restore from CrossWatch back into those providers.
- Automatic snapshots
- When CrossWatch is used as a target, it can automatically create snapshots of its data before changes are applied.
- Snapshots are timestamped JSON files per feature.
- You control:
- Retention (days) – how long old snapshots are kept.
- Max snapshots per feature – hard cap per feature.
- Auto snapshot on/off – decide if a backup/snapshot is taken before each update.
- Quick snapshot switching from the dashboard
- In Dashboard → Insights, click the CrossWatch tile while on Watchlist, Ratings or History.
- A small picker opens where you can:
- Switch to any available snapshot for that feature.
- Or go back to Latest with one click.
Read here for more information about the new CrossWatch Tracker. https://github.com/cenodude/CrossWatch/wiki/mod_CROSSWATCH
🔧 Fixes & Changes
- Fixed: In Dashboard → Insights, large provider numbers now auto-scale so big counts no longer get cut off in the tiles.
- Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- All maintenance actions are now grouped in a single, compact dialog, with clear descriptions per action.
- Changed: The old “User Interface” section in Settings is now simply called Settings, and contains two groups: user interface and CrossWatch tracker.
- Changed: Insights; see which snapshot is active when using CrossWatch tracker.
- In Dashboard → Insights, the CrossWatch tile shows:
- For Latest (default) → a “Latest” label.
- For a specific snapshot → the snapshot date (e.g.
dd-month-yy). - Or use the snapshot switching in the dashboard.
- In Dashboard → Insights, the CrossWatch tile shows:
CrossWatch – v0.4.3
Small release with targeted UI polish and stability improvements.
🔧 Fixes & Changes
- Fixed: Jellyfin server availability is now actively probed, so the banner correctly switches to “down” when the server is unreachable.
- Fixed: Sync progress bar visuals have been tuned; progress flows smoother across phases and reliably reaches 100% when the task completes.
- Fixed: Dashboard lanes no longer flicker or reuse stale data; a no-op sync (0 changes) now correctly shows empty lanes.
- Changed: Dashboard spotlight items (Watchlist / Ratings / History) are now ordered newest-first instead of oldest-first.
- Changed: Each lane now includes a More chip that opens a modal with the last 25 items. Use the Analyzer for a full list.
- Changed: Probe caching is now more aggressive, reducing the number of outbound API calls.
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first: https://github.com/cenodude/CrossWatch/wiki/Best-Practices
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools: https://github.com/cenodude/CrossWatch/wiki/Appendix---Script-folderplex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
Smaller, more reliable, and they handle missing/unreachable servers without crashing. These are essentially my test scripts to clean up, back up, and restore Plex/Emby/Jellyfin states.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- After upgrade, go to Settings and click the big red Save config button; then open each Pair and save it (even if unchanged) to normalize config.json.
- Review library whitelisting settings per provider as they now enforce scope restrictions.
- Config format changed; existing setups may break until config is saved again (Settings → Save).
- Pair library selector now respects server‑level whitelists and disables Start button if required accounts are missing.
- Now Playing bar at bottom displays current title, year/episode info, and live progress.
- Server‑level and pair‑level library whitelisting for scoped history/ratings syncs.
- Improved scheduled sync visibility in Dashboard → Insights.
Full changelog
CrossWatch – v0.4.8
This will be the last functional update for a while. Next up: code cleanup, restructuring, and prep for v0.5.0.
I will still update new 0.4.x releases to fix bugs etc.
In this build the Now Playing card has been completely refreshed. The old tooltip-style “Now Playing” view is gone.
The new Playing card: shows the currently playing movie or show at the bottom of your screen, with backdrop, title, and a progress bar.
Real-time progress is supported for:
- Jellyfin Webhook (make sure Playback Progress is enabled in your Jellyfin webhook)
- Emby and Plex Watcher
Other webhooks (Plex / Emby webhook) do not provide progression updates. That’s on them, not on me.
The Playing card will still render and update when events come in, just without real-time progress.
Don’t like any of this?
You can disable the new Playing card under Settings → UI.
✨ Highlights
-
New “Now Playing” card
- Shows the current movie/show with backdrop, title, and progress bar.
- Updates live from Plex, Emby and Jellyfin while you play, pause or stop.
-
Emby Watcher: now includes real-time progress just like Plex
- When you skip or fast-forward in Emby, the progress now updates much more accurately in the Now Playing card and on Trakt/SIMKL.
-
Improved Trakt matching for Emby & Jellyfin
- Better detection of the correct show + episode on Trakt, even with strange IDs.
🔧 Fixes & Changes
- Changed: Improved Jellyfin webhook to support real-time progress. Note: You need to enable Playback Progress in your webhook!
- Changed: Trakt ID lookups (movie/show/episode) are now cached, reducing Trakt API calls.
- Changed: Default scrobble guard behavior (pause debounce, autoplay protection) tuned for fewer accidental scrobbles.
CrossWatch – v0.4.7
Plex’s “Mark as watched” and its actual play history are two different signals.
Until now, CrossWatch played it safe and only trusted real play history, completely ignoring items that were just marked as watched.
Enough people ran into that limitation that it was time to fix it.
With this release, CrossWatch now understands both – real plays and “marked watched”.
If you prefer the old behavior, just turn off Marked Watched under Pair → Providers → Plex.
MOD_PLEX WIKI page has been updated. https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
✨ Highlights
- Plex “Marked Watched” support
- In Pair → Providers → Plex you’ll now see a new toggle next to Fallback GUID called Marked Watched default is enabled.
- When this is enabled, CrossWatch will also look at Plex’s library “watched” state, not just the play history.
- That means:
- If you marked items as watched in Plex (without real play history), CrossWatch can now pick those up and sync them out.
🔧 Fixes & Changes
-
Stricter timestamps (no fake dates)
- For both real history and “marked watched” entries, CrossWatch now only uses items that have a real timestamp from Plex.
- If Plex doesn’t give a timestamp, that item is simply ignored for history sync.
- We no longer invent “watched_at = now”
-
Important: “Marked Watched” is one-way (adds only, no remove)
- Enabling Marked Watched makes CrossWatch treat things as watched:
- If Plex says an item is watched (history or marked watched), CrossWatch will sync that as watched.
- But there is no unwatch sync:
- If you unmark something as watched in Plex, CrossWatch will not go and remove/undo that play. That's just too risky.
- This is deliberate. Plex doesn’t emit a clean event, and trying to guess removals is a great way to wipe people’s history by accident.
- Enabling Marked Watched makes CrossWatch treat things as watched:
CrossWatch – v0.4.6
Sorry....Previously, a small CSS blending issue caused the Editor layout to break if you opened the Watchlist first. This has now been fixed.
I didn’t want to keep you waiting, so here’s the second update for today.
✨ Highlights
- Metadata search for CW Editor
- New compact, neon-style “Search metadata” popup that shows small posters for each result.
- Picking a result now automatically fills TMDb, IMDb, and Trakt IDs where available.
- The Key column is filled for you in the format
imdb:tt1234567when an IMDb ID is known.
🔧 Fixes & Changes
- Fixed: Opening Watchlist before the Editor could mess up the Editor layout.
- The Editor now keeps its layout intact when switching between pages, no refresh needed.
- Improved: Trakt connection is more reliable.
- Expired Trakt logins are refreshed automatically more often, reducing “Trakt disconnected” errors.
CrossWatch – v0.4.5
CrossWatch v0.4.5 makes it much easier to inspect, clean up, and repair your tracker data when something looks off.
This release introduces the CrossWatch Tracker Editor, so you can browse, filter, and edit Watchlist / History / Ratings in a structured table instead of digging through raw files.
Read more: https://github.com/cenodude/CrossWatch/wiki/Editor
I’m parking feature work for a bit and focusing on bug fixes only, my ass needs a little break.
✨ Highlights
- CrossWatch Tracker Editor
- Dedicated editor for CW tracker Watchlist / History / Ratings with search, paging, and inline editing.
- Backup and Restore
🔧 Fixes & Changes
-
Fixed: Items from Trakt sometimes showed up as “Untitled” in the tracker/analyzer
- Episode history and ratings from Trakt now correctly display their show/episode titles.
-
Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- Added Remove metadata cache to wipe cached posters and metadata.
- Added Clean Everything button that runs all maintenance actions in one go.
-
Added: CW Tracker Editor
- Edit tracker data for Watchlist, History, and Ratings in a single table.
- Global search bar, paging controls, and column sorting for Key, Type, Title, and Extra.
- Per-type filter chips to quickly show only Movies, Shows, or Episodes.
- Side panel with live stats: total rows, visible rows, and counts for movies/shows/episodes.
- Backup and restore: The editor also includes simple import/export tools to move tracker data around or create backups.
-
Changed: Snapshot naming handling
- Snapshot dropdowns now show friendly labels like
2025-11-28 - 11:43instead of raw filenames. - Snapshot picker inside Insights only lists the 10 most recent snapshots per feature to avoid huge lists.
- “Latest” snapshot is always available as a quick option.
- Snapshot dropdowns now show friendly labels like
-
Improved: Watchlist
- Only providers that actually synced for the list are shown.
- The CrossWatch provider label is shortened to “CW” in List Insight for a cleaner layout.
- Limits the amount of rows and/or posters to 50 at a time.
CrossWatch – v0.4.4
Small version bump, big changes.
A mistake is easily made, one bad sync, one wrong setting, and things can get messy fast.
This release is all about the new CrossWatch Tracker A built-in snapshot provider that stores your Watchlist, History and Ratings locally and lets you restore them into your other services.
Future CW versions will push this further with an editor and more advanced tools, giving you even more control over your data.
✨ Highlights
- CrossWatch Tracker (internal snapshot provider) - experimental, meaning: expect bugs.
- New provider card: CROSSWATCH
- Can be used like any other provider in a pair:
- As target → backup/snapshot from providers into CrossWatch.
- As source → restore from CrossWatch back into those providers.
- Automatic snapshots
- When CrossWatch is used as a target, it can automatically create snapshots of its data before changes are applied.
- Snapshots are timestamped JSON files per feature.
- You control:
- Retention (days) – how long old snapshots are kept.
- Max snapshots per feature – hard cap per feature.
- Auto snapshot on/off – decide if a backup/snapshot is taken before each update.
- Quick snapshot switching from the dashboard
- In Dashboard → Insights, click the CrossWatch tile while on Watchlist, Ratings or History.
- A small picker opens where you can:
- Switch to any available snapshot for that feature.
- Or go back to Latest with one click.
Read here for more information about the new CrossWatch Tracker. https://github.com/cenodude/CrossWatch/wiki/mod_CROSSWATCH
🔧 Fixes & Changes
- Fixed: In Dashboard → Insights, large provider numbers now auto-scale so big counts no longer get cut off in the tiles.
- Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- All maintenance actions are now grouped in a single, compact dialog, with clear descriptions per action.
- Changed: The old “User Interface” section in Settings is now simply called Settings, and contains two groups: user interface and CrossWatch tracker.
- Changed: Insights; see which snapshot is active when using CrossWatch tracker.
- In Dashboard → Insights, the CrossWatch tile shows:
- For Latest (default) → a “Latest” label.
- For a specific snapshot → the snapshot date (e.g.
dd-month-yy). - Or use the snapshot switching in the dashboard.
- In Dashboard → Insights, the CrossWatch tile shows:
CrossWatch – v0.4.3
Small release with targeted UI polish and stability improvements.
🔧 Fixes & Changes
- Fixed: Jellyfin server availability is now actively probed, so the banner correctly switches to “down” when the server is unreachable.
- Fixed: Sync progress bar visuals have been tuned; progress flows smoother across phases and reliably reaches 100% when the task completes.
- Fixed: Dashboard lanes no longer flicker or reuse stale data; a no-op sync (0 changes) now correctly shows empty lanes.
- Changed: Dashboard spotlight items (Watchlist / Ratings / History) are now ordered newest-first instead of oldest-first.
- Changed: Each lane now includes a More chip that opens a modal with the last 25 items. Use the Analyzer for a full list.
- Changed: Probe caching is now more aggressive, reducing the number of outbound API calls.
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first: https://github.com/cenodude/CrossWatch/wiki/Best-Practices
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools: https://github.com/cenodude/CrossWatch/wiki/Appendix---Script-folderplex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
Smaller, more reliable, and they handle missing/unreachable servers without crashing. These are essentially my test scripts to clean up, back up, and restore Plex/Emby/Jellyfin states.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- After upgrading, navigate to Settings and click the big red Save button to ensure the new Marked Watched config entry is persisted.
- "Marked Watched" sync is one‑way: enabling it will only add watched entries; unwatch actions in Plex are not propagated.
- Plex “Marked Watched” toggle (enabled by default) in Pair → Providers → Plex
- Stricter timestamp handling – items without a real timestamp from Plex are ignored
Full changelog
CrossWatch – v0.4.7
Plex’s “Mark as watched” and its actual play history are two different signals.
Until now, CrossWatch played it safe and only trusted real play history, completely ignoring items that were just marked as watched.
Enough people ran into that limitation that it was time to fix it.
With this release, CrossWatch now understands both, real plays and “marked watched”.
If you prefer the old behavior, just turn off Marked Watched under Pair → Providers → Plex.
IMPORTANT: Since I’ve added a new setting to the config, make sure you hit the big red Save button in Settings so it’s included.
MOD_PLEX WIKI page has been updated.
✨ Highlights
- Plex “Marked Watched” support
- In Pair → Providers → Plex you’ll now see a new toggle next to Fallback GUID called Marked Watched default is enabled.
- When this is enabled, CrossWatch will also look at Plex’s library “watched” state, not just the play history.
- That means:
- If you marked items as watched in Plex (without real play history), CrossWatch can now pick those up and sync them out.
🔧 Fixes & Changes
-
Stricter timestamps (no fake dates)
- For both real history and “marked watched” entries, CrossWatch now only uses items that have a real timestamp from Plex.
- If Plex doesn’t give a timestamp, that item is simply ignored for history sync.
- I'm no longer invent “watched_at = now”
-
Important: “Marked Watched” is one-way (adds only, no remove)
- Enabling Marked Watched makes CrossWatch treat things as watched:
- If Plex says an item is watched (history or marked watched), CrossWatch will sync that as watched.
- But there is no unwatch sync:
- If you unmark something as watched in Plex, CrossWatch will not go and remove/undo that play. That's just too risky.
- This is deliberate. Plex doesn’t emit a clean event, and trying to guess removals is a great way to wipe people’s history by accident.
- Enabling Marked Watched makes CrossWatch treat things as watched:
CrossWatch – v0.4.6
Sorry....Previously, a small CSS blending issue caused the Editor layout to break if you opened the Watchlist first. This has now been fixed.
I didn’t want to keep you waiting, so here’s the second update for today.
✨ Highlights
- Metadata search for CW Editor
- New compact, neon-style “Search metadata” popup that shows small posters for each result.
- Picking a result now automatically fills TMDb, IMDb, and Trakt IDs where available.
- The Key column is filled for you in the format
imdb:tt1234567when an IMDb ID is known.
🔧 Fixes & Changes
- Fixed: Opening Watchlist before the Editor could mess up the Editor layout.
- The Editor now keeps its layout intact when switching between pages, no refresh needed.
- Improved: Trakt connection is more reliable.
- Expired Trakt logins are refreshed automatically more often, reducing “Trakt disconnected” errors.
CrossWatch – v0.4.5
CrossWatch v0.4.5 makes it much easier to inspect, clean up, and repair your tracker data when something looks off.
This release introduces the CrossWatch Tracker Editor, so you can browse, filter, and edit Watchlist / History / Ratings in a structured table instead of digging through raw files.
Read more: https://github.com/cenodude/CrossWatch/wiki/Editor
I’m parking feature work for a bit and focusing on bug fixes only, my ass needs a little break.
✨ Highlights
- CrossWatch Tracker Editor
- Dedicated editor for CW tracker Watchlist / History / Ratings with search, paging, and inline editing.
- Backup and Restore
🔧 Fixes & Changes
-
Fixed: Items from Trakt sometimes showed up as “Untitled” in the tracker/analyzer
- Episode history and ratings from Trakt now correctly display their show/episode titles.
-
Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- Added Remove metadata cache to wipe cached posters and metadata.
- Added Clean Everything button that runs all maintenance actions in one go.
-
Added: CW Tracker Editor
- Edit tracker data for Watchlist, History, and Ratings in a single table.
- Global search bar, paging controls, and column sorting for Key, Type, Title, and Extra.
- Per-type filter chips to quickly show only Movies, Shows, or Episodes.
- Side panel with live stats: total rows, visible rows, and counts for movies/shows/episodes.
- Backup and restore: The editor also includes simple import/export tools to move tracker data around or create backups.
-
Changed: Snapshot naming handling
- Snapshot dropdowns now show friendly labels like
2025-11-28 - 11:43instead of raw filenames. - Snapshot picker inside Insights only lists the 10 most recent snapshots per feature to avoid huge lists.
- “Latest” snapshot is always available as a quick option.
- Snapshot dropdowns now show friendly labels like
-
Improved: Watchlist
- Only providers that actually synced for the list are shown.
- The CrossWatch provider label is shortened to “CW” in List Insight for a cleaner layout.
- Limits the amount of rows and/or posters to 50 at a time.
CrossWatch – v0.4.4
Small version bump, big changes.
A mistake is easily made, one bad sync, one wrong setting, and things can get messy fast.
This release is all about the new CrossWatch Tracker A built-in snapshot provider that stores your Watchlist, History and Ratings locally and lets you restore them into your other services.
Future CW versions will push this further with an editor and more advanced tools, giving you even more control over your data.
✨ Highlights
- CrossWatch Tracker (internal snapshot provider) - experimental, meaning: expect bugs.
- New provider card: CROSSWATCH
- Can be used like any other provider in a pair:
- As target → backup/snapshot from providers into CrossWatch.
- As source → restore from CrossWatch back into those providers.
- Automatic snapshots
- When CrossWatch is used as a target, it can automatically create snapshots of its data before changes are applied.
- Snapshots are timestamped JSON files per feature.
- You control:
- Retention (days) – how long old snapshots are kept.
- Max snapshots per feature – hard cap per feature.
- Auto snapshot on/off – decide if a backup/snapshot is taken before each update.
- Quick snapshot switching from the dashboard
- In Dashboard → Insights, click the CrossWatch tile while on Watchlist, Ratings or History.
- A small picker opens where you can:
- Switch to any available snapshot for that feature.
- Or go back to Latest with one click.
Read here for more information about the new CrossWatch Tracker. https://github.com/cenodude/CrossWatch/wiki/mod_CROSSWATCH
🔧 Fixes & Changes
- Fixed: In Dashboard → Insights, large provider numbers now auto-scale so big counts no longer get cut off in the tiles.
- Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- All maintenance actions are now grouped in a single, compact dialog, with clear descriptions per action.
- Changed: The old “User Interface” section in Settings is now simply called Settings, and contains two groups: user interface and CrossWatch tracker.
- Changed: Insights; see which snapshot is active when using CrossWatch tracker.
- In Dashboard → Insights, the CrossWatch tile shows:
- For Latest (default) → a “Latest” label.
- For a specific snapshot → the snapshot date (e.g.
dd-month-yy). - Or use the snapshot switching in the dashboard.
- In Dashboard → Insights, the CrossWatch tile shows:
CrossWatch – v0.4.3
Small release with targeted UI polish and stability improvements.
🔧 Fixes & Changes
- Fixed: Jellyfin server availability is now actively probed, so the banner correctly switches to “down” when the server is unreachable.
- Fixed: Sync progress bar visuals have been tuned; progress flows smoother across phases and reliably reaches 100% when the task completes.
- Fixed: Dashboard lanes no longer flicker or reuse stale data; a no-op sync (0 changes) now correctly shows empty lanes.
- Changed: Dashboard spotlight items (Watchlist / Ratings / History) are now ordered newest-first instead of oldest-first.
- Changed: Each lane now includes a More chip that opens a modal with the last 25 items. Use the Analyzer for a full list.
- Changed: Probe caching is now more aggressive, reducing the number of outbound API calls.
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first: https://github.com/cenodude/CrossWatch/wiki/Best-Practices
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools: https://github.com/cenodude/CrossWatch/wiki/Appendix---Script-folderplex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
Smaller, more reliable, and they handle missing/unreachable servers without crashing. These are essentially my test scripts to clean up, back up, and restore Plex/Emby/Jellyfin states.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
CrossWatch v0.4.6 fixes a CSS blending issue that broke the Editor layout when opening Watchlist first.
Full changelog
CrossWatch – v0.4.6
Sorry....Previously, a small CSS blending issue caused the Editor layout to break if you opened the Watchlist first. This has now been fixed.
I didn’t want to keep you waiting, so here’s the second update for today.
✨ Highlights
- Metadata search for CW Editor
- New “Search metadata” popup that shows small posters for each result.
- Picking a result now automatically fills TMDb, IMDb, and Trakt IDs where available.
- The Key column is filled for you in the format
imdb:tt1234567when an IMDb ID is known.
🔧 Fixes & Changes
- Fixed: Opening Watchlist before the Editor could mess up the Editor layout.
- The Editor now keeps its layout intact when switching between pages, no refresh needed.
- Improved: Trakt connection is more reliable.
- Expired Trakt logins are refreshed automatically more often, reducing “Trakt disconnected” errors.
As v0.4.6 is a quick patch release, please also read v0.4.5 Below
CrossWatch – v0.4.5
CrossWatch v0.4.5 makes it much easier to inspect, clean up, and repair your tracker data when something looks off.
This release introduces the CrossWatch Tracker Editor, so you can browse, filter, and edit Watchlist / History / Ratings in a structured table instead of digging through raw files.
Read more at WIKI
I’m parking feature work for a bit and focusing on bug fixes only, my ass needs a little break.
✨ Highlights
- CrossWatch Tracker Editor
- Dedicated editor for CW tracker Watchlist / History / Ratings with search, paging, and inline editing.
- Backup and Restore
🔧 Fixes & Changes
-
Fixed: Items from Trakt sometimes showed up as “Untitled” in the tracker/analyzer
- Episode history and ratings from Trakt now correctly display their show/episode titles.
-
Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- Added Remove metadata cache to wipe cached posters and metadata.
- Added Clean Everything button that runs all maintenance actions in one go.
-
Added: CW Tracker Editor
- Edit tracker data for Watchlist, History, and Ratings in a single table.
- Global search bar, paging controls, and column sorting for Key, Type, Title, and Extra.
- Per-type filter chips to quickly show only Movies, Shows, or Episodes.
- Side panel with live stats: total rows, visible rows, and counts for movies/shows/episodes.
- Backup and restore: The editor also includes simple import/export tools to move tracker data around or create backups.
-
Changed: Snapshot naming handling
- Snapshot dropdowns now show friendly labels like
2025-11-28 - 11:43instead of raw filenames. - Snapshot picker inside Insights only lists the 10 most recent snapshots per feature to avoid huge lists.
- “Latest” snapshot is always available as a quick option.
- Snapshot dropdowns now show friendly labels like
-
Improved: Watchlist
- Only providers that actually synced for the list are shown.
- The CrossWatch provider label is shortened to “CW” in List Insight for a cleaner layout.
- Limits the amount of rows and/or posters to 50 at a time.
CrossWatch – v0.4.4
Small version bump, big changes.
A mistake is easily made, one bad sync, one wrong setting, and things can get messy fast.
This release is all about the new CrossWatch Tracker A built-in snapshot provider that stores your Watchlist, History and Ratings locally and lets you restore them into your other services.
Future CW versions will push this further with an editor and more advanced tools, giving you even more control over your data.
✨ Highlights
- CrossWatch Tracker (internal snapshot provider) - experimental, meaning: expect bugs.
- New provider card: CROSSWATCH
- Can be used like any other provider in a pair:
- As target → backup/snapshot from providers into CrossWatch.
- As source → restore from CrossWatch back into those providers.
- Automatic snapshots
- When CrossWatch is used as a target, it can automatically create snapshots of its data before changes are applied.
- Snapshots are timestamped JSON files per feature.
- You control:
- Retention (days) – how long old snapshots are kept.
- Max snapshots per feature – hard cap per feature.
- Auto snapshot on/off – decide if a backup/snapshot is taken before each update.
- Quick snapshot switching from the dashboard
- In Dashboard → Insights, click the CrossWatch tile while on Watchlist, Ratings or History.
- A small picker opens where you can:
- Switch to any available snapshot for that feature.
- Or go back to Latest with one click.
Read here for more information about the new CrossWatch Tracker. https://github.com/cenodude/CrossWatch/wiki/mod_CROSSWATCH
🔧 Fixes & Changes
- Fixed: In Dashboard → Insights, large provider numbers now auto-scale so big counts no longer get cut off in the tiles.
- Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- All maintenance actions are now grouped in a single, compact dialog, with clear descriptions per action.
- Changed: The old “User Interface” section in Settings is now simply called Settings, and contains two groups: user interface and CrossWatch tracker.
- Changed: Insights; see which snapshot is active when using CrossWatch tracker.
- In Dashboard → Insights, the CrossWatch tile shows:
- For Latest (default) → a “Latest” label.
- For a specific snapshot → the snapshot date (e.g.
dd-month-yy). - Or use the snapshot switching in the dashboard.
- In Dashboard → Insights, the CrossWatch tile shows:
CrossWatch – v0.4.3
Small release with targeted UI polish and stability improvements.
🔧 Fixes & Changes
- Fixed: Jellyfin server availability is now actively probed, so the banner correctly switches to “down” when the server is unreachable.
- Fixed: Sync progress bar visuals have been tuned; progress flows smoother across phases and reliably reaches 100% when the task completes.
- Fixed: Dashboard lanes no longer flicker or reuse stale data; a no-op sync (0 changes) now correctly shows empty lanes.
- Changed: Dashboard spotlight items (Watchlist / Ratings / History) are now ordered newest-first instead of oldest-first.
- Changed: Each lane now includes a More chip that opens a modal with the last 25 items. Use the Analyzer for a full list.
- Changed: Probe caching is now more aggressive, reducing the number of outbound API calls.
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first: https://github.com/cenodude/CrossWatch/wiki/Best-Practices
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools: https://github.com/cenodude/CrossWatch/wiki/Appendix---Script-folderplex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
Smaller, more reliable, and they handle missing/unreachable servers without crashing. These are essentially my test scripts to clean up, back up, and restore Plex/Emby/Jellyfin states.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- After upgrading, go to Settings and click the big red **Save config** button once.
- Open each Pair configuration page and click **Save** (even without changes) to rewrite normalized JSON.
- Review the Whitelisting section in Settings → Insights for new library whitelist controls.
- Changed config format in v0.4.0; existing `config.json` must be saved via Settings and each Pair re‑saved to normalize.
- New server‑level and pair‑level library whitelists introduced, altering which libraries are synced.
- Now Playing bar at the bottom showing current title, year, episode info with live progress.
- Library whitelisting (server‑level & pair‑level) to limit sync scope for History and Ratings.
- Improved scheduled syncs appear in Dashboard → Insights alongside manual runs.
Full changelog
CrossWatch – v0.4.5
CrossWatch v0.4.5 makes it easy to inspect, clean up, and repair your CW tracker data when something looks off.
This release introduces the CW Tracker Editor, so you can browse, filter, and edit Watchlist / History / Ratings in a structured table instead of digging through raw files. Read more at WIKI
I’m pausing new features for a bit and focusing on bug fixes only — my ass needs a short break. I’ll use the time to clean up the code and prep for 0.5.0. I’ll be back in a few days… try not to miss me too much 😄
✨ Highlights
- CrossWatch Tracker Editor
- Dedicated editor for CW tracker Watchlist / History / Ratings with search, paging, and inline editing.
- Backup and Restore
🔧 Fixes & Changes
-
Fixed: Items from Trakt sometimes showed up as “Untitled” in the tracker/analyzer
- Episode history and ratings from Trakt now correctly display their show/episode titles.
-
Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- Added Remove metadata cache to wipe cached posters and metadata.
- Added Clean Everything button that runs all maintenance actions in one go.
-
Added: CW Tracker Editor
- Edit tracker data for Watchlist, History, and Ratings in a single table.
- Global search bar, paging controls, and column sorting for Key, Type, Title, and Extra.
- Per-type filter chips to quickly show only Movies, Shows, or Episodes.
- Side panel with live stats: total rows, visible rows, and counts for movies/shows/episodes.
- Backup and restore: The editor also includes simple import/export tools to move tracker data around or create backups.
-
Changed: Snapshot naming handling
- Snapshot dropdowns now show friendly labels like
2025-11-28 - 11:43instead of raw filenames. - Snapshot picker inside Insights only lists the 10 most recent snapshots per feature to avoid huge lists.
- “Latest” snapshot is always available as a quick option.
- Snapshot dropdowns now show friendly labels like
-
Improved: Watchlist
- Only providers that actually synced for the list are shown.
- The CrossWatch provider label is shortened to “CW” in List Insight for a cleaner layout.
- Limits the amount of rows and/or posters to 50 at a time.
CrossWatch – v0.4.4
Small version bump, big changes.
A mistake is easily made, one bad sync, one wrong setting, and things can get messy fast.
This release is all about the new CrossWatch Tracker A built-in snapshot provider that stores your Watchlist, History and Ratings locally and lets you restore them into your other services.
Future CW versions will push this further with an editor and more advanced tools, giving you even more control over your data.
✨ Highlights
- CrossWatch Tracker (internal snapshot provider) - experimental, meaning: expect bugs.
- New provider card: CROSSWATCH
- Can be used like any other provider in a pair:
- As target → backup/snapshot from providers into CrossWatch.
- As source → restore from CrossWatch back into those providers.
- Automatic snapshots
- When CrossWatch is used as a target, it can automatically create snapshots of its data before changes are applied.
- Snapshots are timestamped JSON files per feature.
- You control:
- Retention (days) – how long old snapshots are kept.
- Max snapshots per feature – hard cap per feature.
- Auto snapshot on/off – decide if a backup/snapshot is taken before each update.
- Quick snapshot switching from the dashboard
- In Dashboard → Insights, click the CrossWatch tile while on Watchlist, Ratings or History.
- A small picker opens where you can:
- Switch to any available snapshot for that feature.
- Or go back to Latest with one click.
Read here for more information about the new CrossWatch Tracker. https://github.com/cenodude/CrossWatch/wiki/mod_CROSSWATCH
🔧 Fixes & Changes
- Fixed: In Dashboard → Insights, large provider numbers now auto-scale so big counts no longer get cut off in the tiles.
- Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- All maintenance actions are now grouped in a single, compact dialog, with clear descriptions per action.
- Changed: The old “User Interface” section in Settings is now simply called Settings, and contains two groups: user interface and CrossWatch tracker.
- Changed: Insights; see which snapshot is active when using CrossWatch tracker.
- In Dashboard → Insights, the CrossWatch tile shows:
- For Latest (default) → a “Latest” label.
- For a specific snapshot → the snapshot date (e.g.
dd-month-yy). - Or use the snapshot switching in the dashboard.
- In Dashboard → Insights, the CrossWatch tile shows:
CrossWatch – v0.4.3
Small release with targeted UI polish and stability improvements.
🔧 Fixes & Changes
- Fixed: Jellyfin server availability is now actively probed, so the banner correctly switches to “down” when the server is unreachable.
- Fixed: Sync progress bar visuals have been tuned; progress flows smoother across phases and reliably reaches 100% when the task completes.
- Fixed: Dashboard lanes no longer flicker or reuse stale data; a no-op sync (0 changes) now correctly shows empty lanes.
- Changed: Dashboard spotlight items (Watchlist / Ratings / History) are now ordered newest-first instead of oldest-first.
- Changed: Each lane now includes a More chip that opens a modal with the last 25 items. Use the Analyzer for a full list.
- Changed: Probe caching is now more aggressive, reducing the number of outbound API calls.
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first: https://github.com/cenodude/CrossWatch/wiki/Best-Practices
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools: https://github.com/cenodude/CrossWatch/wiki/Appendix---Script-folderplex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
Smaller, more reliable, and they handle missing/unreachable servers without crashing. These are essentially my test scripts to clean up, back up, and restore Plex/Emby/Jellyfin states.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- After upgrading to v0.4.0, go to Settings and click the big red **Save config** button once.
- Open each Pair configuration page and click **Save** (even if unchanged) to rewrite and normalize `config.json` for the new behavior.
- Config parsing and structure changed in v0.4.0; existing config.json must be re‑saved via Settings to normalize, otherwise the application may fail.
- Library whitelisting introduced at server‑level and pair‑level, altering which libraries are considered for history/ratings sync.
- Now Playing bar showing live playback details with hover info
- Experimental library whitelisting (server‑level & pair‑level) with Insights UI section
- Improved scheduled sync visibility in Dashboard → Insights
Full changelog
CrossWatch – v0.4.4
Small version bump, big changes.
A mistake is easily made, one bad sync, one wrong setting, and things can get messy fast.
This release is all about the new CrossWatch Tracker A built-in snapshot provider that stores your Watchlist, History and Ratings locally and lets you restore them into your other services.
Future CW versions will push this further with an editor and more advanced tools, giving you even more control over your data.
✨ Highlights
- CrossWatch Tracker (internal snapshot provider) - experimental, meaning: expect bugs.
- New provider card: CROSSWATCH
- Can be used like any other provider in a pair:
- As target → backup/snapshot from providers into CrossWatch.
- As source → restore from CrossWatch back into those providers.
- Automatic snapshots
- When CrossWatch is used as a target, it can automatically create snapshots of its data before changes are applied.
- Snapshots are timestamped JSON files per feature.
- You control:
- Retention (days) – how long old snapshots are kept.
- Max snapshots per feature – hard cap per feature.
- Auto snapshot on/off – decide if a backup/snapshot is taken before each update.
- Quick snapshot switching from the dashboard
- In Dashboard → Insights, click the CrossWatch tile while on Watchlist, Ratings or History.
- A small picker opens where you can:
- Switch to any available snapshot for that feature.
- Or go back to Latest with one click.
Read here for more information about the new CrossWatch Tracker.
🔧 Fixes & Changes
- Fixed: In Dashboard → Insights, large provider numbers now auto-scale so big counts no longer get cut off in the tiles.
- Changed: Maintenance tools modal (Settings → Maintenance → Maintenance Tools)
- All maintenance actions are now grouped in a single, compact dialog, with clear descriptions per action.
- Changed: The old “User Interface” section in Settings is now simply called Settings, and contains two groups: user interface and CrossWatch tracker.
- Changed: Insights; see which snapshot is active when using CrossWatch tracker.
- In Dashboard → Insights, the CrossWatch tile shows:
- For Latest (default) → a “Latest” label.
- For a specific snapshot → the snapshot date (e.g.
dd-month-yy). - Or use the snapshot switching in the dashboard.
- In Dashboard → Insights, the CrossWatch tile shows:
CrossWatch – v0.4.3
Small release with targeted UI polish and stability improvements.
🔧 Fixes & Changes
- Fixed: Jellyfin server availability is now actively probed, so the banner correctly switches to “down” when the server is unreachable.
- Fixed: Sync progress bar visuals have been tuned; progress flows smoother across phases and reliably reaches 100% when the task completes.
- Fixed: Dashboard lanes no longer flicker or reuse stale data; a no-op sync (0 changes) now correctly shows empty lanes.
- Changed: Dashboard spotlight items (Watchlist / Ratings / History) are now ordered newest-first instead of oldest-first.
- Changed: Each lane now includes a More chip that opens a modal with the last 25 items. Use the Analyzer for a full list.
- Changed: Probe caching is now more aggressive, reducing the number of outbound API calls.
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first: https://github.com/cenodude/CrossWatch/wiki/Best-Practices
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools: https://github.com/cenodude/CrossWatch/wiki/Appendix---Script-folderplex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
Smaller, more reliable, and they handle missing/unreachable servers without crashing. These are essentially my test scripts to clean up, back up, and restore Plex/Emby/Jellyfin states.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- After upgrading to v0.4.0, go to Settings and click the big red Save config button once.
- Open each Pair configuration and click Save (even if unchanged) to normalize `config.json`.
- Review the Whitelisting section in Settings → Insights and consult the wiki for usage details.
- Config schema changed; saved configs must be refreshed via Settings → Save config and each Pair → Save.
- Library whitelisting (server‑level and pair‑level) replaces previous unrestricted sync behavior.
- Now Playing bar showing live title, year, episode info with hover progress.
- Experimental server‑level and pair‑level library whitelists for History/Ratings sync.
- Improved scheduled sync visibility in Dashboard → Insights (Recent syncs).
Full changelog
CrossWatch – v0.4.3
Small release with some UI polish and improvements, and likely the last update for the coming days.
🔧 Fixes & Changes
- Fixed: Jellyfin server availability is now actively probed, so the banner correctly switches to “down” when the server is unreachable.
- Fixed: Sync progress bar visuals have been tuned; progress is more reliably reaches 100% when the task completes.
- Fixed: Dashboard lanes no longer flicker or reuse stale data; a no-op sync (0 changes) now correctly shows empty lanes.
- Changed: Dashboard spotlight items (Watchlist / Ratings / History) are now ordered newest-first instead of oldest-first.
- Changed: Each lane now includes a More chip that opens a modal with the last 25 items. Use the Analyzer for a full list.
- Changed: Probe caching is now more aggressive, reducing the number of outbound API calls.
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first: https://github.com/cenodude/CrossWatch/wiki/Best-Practices
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools: https://github.com/cenodude/CrossWatch/wiki/Appendix---Script-folderplex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
Smaller, more reliable, and they handle missing/unreachable servers without crashing. These are essentially my test scripts to clean up, back up, and restore Plex/Emby/Jellyfin states.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- History Remove toggle/button restored in Pair config for delete‑sync
Full changelog
CrossWatch – v0.4.2
This release improves sync reliability between media servers (Plex, Emby, Jellyfin), especially for History and Ratings.
The Remove toggle is also back in the Pair config for History.
Warning: For both Ratings and History, DO NOT enable REMOVE unless you really know why. It only makes sense in rare mirroring setups between media servers.
🔧 Fixes & Changes
- Fixed: Emby History sync from Plex is now more reliable. CrossWatch preserves Plex external IDs and uses show-level IDs when episode IDs aren’t present, avoiding silent misses.
- Fixed: Jellyfin History sync received the same resolver upgrade (show-level ID fallback + looser series-title matching), preventing false “unresolved” items when the show exists.
- Fixed: Jellyfin Ratings sync is hardened. Key mismatches no longer cause repeated retries or stuck ratings.
- Fixed: MDBList Ratings sync: removing ratings (including season/episode ratings) now cleans up correctly, stopping repeated “unrate” attempts.
- Fixed: Sync output no longer logs each pair twice; duplicate
run:pairmessages were removed. - Change: The History Remove toggle/button is available again in Pair config, so delete-sync can be enabled when needed. Read the wiki first:
- Change: Cleanup helpers in
/scripts/were refactored into provider-specific tools:plex_cleanup.pyjellyfin_cleanup.pyemby_cleanup.py
These started as my own test scripts for cleaning up, backing up, and restoring Plex/Emby/Jellyfin states, but they may also be useful for others.
- Note: Script “backups” are API snapshots only (watchlist/history/ratings). They are not full server/database backups.
🧪 Sync adapters/modules updated
- MOD_JELLYFIN: updated from 1.0.0 to 1.0.1
- MOD_MDBList: updated from 1.0.0 to 1.0.1
- MOD_EMBY: updated from 1.0.0 to 1.0.1
- MOD_PLEX: updated from 2.0.0 to 2.0.1
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- After upgrading to v0.4.0, go to Settings and click the big red Save config button once; then open each Pair and click Save (even if unchanged) to rewrite and normalize `config.json`.
- Consult the wiki for details on library whitelisting limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
- v0.4.0 changes how config is read and applies new server‑level & pair‑level whitelists, requiring existing configs to be refreshed (Settings → Save config + save each Pair).
- Now Playing bar at the bottom shows live title, year, episode info with a progress indicator.
- Library whitelisting (server-level and pair-level) experimental feature for controlling which libraries are synced.
- Improved scheduled syncs now appear in Dashboard → Insights along with manual runs.
Full changelog
CrossWatch – v0.4.1
Emby Webhook has now been properly tested. The Watcher was already working, but the webhook path hadn’t been validated yet.
Based on real playback tests, a few fixes and tidy-ups landed in this release.
Jellyfin users: use the webhook
Plex and Emby users: you can use either the webhook or the watcher.
The watcher is recommended, it’s smarter and more reliable, but it does generate more network traffic to your Plex/Emby server.
For Emby and Jellyfin setup, check the Webhook guide on the wiki as it requires a specific configuation:
https://github.com/cenodude/CrossWatch/wiki/Webhook
🔧 Fixes & Changes
- Changed: Emby now uses its own dedicated webhook (based on the Jellyfin webhook), so Emby and Jellyfin scrobble independently.
- Fixed: Emby webhook no longer ignores Start events when
guard_autoplay_secondsis set to0. - Fixed: Early Pause/Stop events from Emby no longer trigger Trakt errors; progress is clamped to Trakt’s minimum requirements.
- Changed: Webhook logging is now consistent across Jellyfin, Plex, and Emby. Debug noise stays in DEBUG, and successful actions are logged as INFO.
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind.
The synchronization bar is still drunk sometimes. I've checked it but require some major changes thus will postpone that to v0.5.0 The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- After upgrading to v0.4.0, go to Settings and click the big red Save config button.
- Open each Pair configuration page and click Save (even if unchanged) to normalize `config.json`.
- Review the updated WIKI on library whitelisting for limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
- Config reading logic changed; existing `config.json` must be rewritten via Settings → Save config and each Pair → Save.
- Whitelisting now enforced at both server‑level and pair‑level, altering which libraries are synced.
- Now Playing bar with hover details and live progress indicator
- Library whitelisting (server‑level & pair‑level) for fine‑grained sync control
- Improved scheduled syncs visible in Dashboard → Insights
Full changelog
CrossWatch – v0.4.0
Whoop! Whoop! Another day, another new CrossWatch release – but this time we’re doing a big jump from 0.3.9 → 0.4.0.
This is a big update and focuses on seeing what’s going on (Now Playing, clearer logs, visible schedules) and tightening control over what gets synced (server- and pair-level whitelists).
⚠️ IMPORTANT: this release can break existing setups until configs are refreshed.
Because 0.4.0 changes how config is read and how whitelisting works, it’s strongly recommended to:
- Go to Settings and hit the big red Save config button once.
- Open each Pair, click Save (even if you don’t change anything).
This will rewrite and normalizeconfig.jsonso everything lines up with the new behavior.
Most of my live testing for 0.4.0 was Plex/Emby/Jellyfin → SIMKL. I can’t realistically test every possible scenario in CrossWatch, so please keep that in mind. The sync progress bar still acts up sometimes. I’ve looked into it, but fixing it properly needs bigger changes, so I’m pushing that to v0.5.0.
✨ Highlights
-
Now Playing bar
- A strip at the bottom shows what you’re currently watching.
- Hover to see title, year, episode info, and a live progress bar.
- Completely pointless… which is exactly why it exists...why not?
-
Library whitelisting (server-level & pair-level) - experimental
- In provider settings you can define server-level whitelists for Plex / Jellyfin / Emby, limiting which libraries CrossWatch ever touches for history and ratings.
- Each sync pair now has its own pair-level whitelist, so one pair can sync only Movies while another focuses on Kids or TV-Shows—all within the allowed server scope.
- Updated Analyzer to be pair-level whitelisting aware.
- In Settings → Insights, CrossWatch now shows a dedicated Whitelisting section.
- IMPORTANT read the WIKI on how it exaclty works and their limitations: https://github.com/cenodude/CrossWatch/wiki/Libraries-whitelisting
-
Improved scheduled syncs
- Scheduled syncs now use the same path as the big Synchronize button.
- Finished schedules show up in Dashboard → Insights (including Recent syncs), so you can actually see what ran and when.
-
Improved Plex / Emby Watcher
- Watcher now follows your main server settings more strictly. This means that it reads the Authentication Providers settings and cannot be changed in the Watcher anymore.
- Detects your Plex / Jellyfin / Emby connection as soon as you open Settings → Scrobbler, so in best-case no full reload needed. Doesnt work? do a manual refresh.
- When you choose Trakt, SIMKL, or Both as the sink, CrossWatch checks that those accounts are connected and tells you what’s missing (if any)
-
Watchlist Preview toggle
- In Settings → User Interface you can hide or show the Watchlist Preview on the main page. Default is enabled.
-
Sync modules / adapters
- mdblist adapter promoted to version 1.0.0 (stable).
- Jellyfin adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- Emby adapter promoted to version 1.0.0 (stable but still can have some new issues) - had some major code changes
- SIMKL adapter promoted to version 2.0.0 (stable and advanced)
-
Clearer watcher/webhook activity logs by centralized logger
- All automatic plays now use one clean, readable log style through the centralized logger.
🔧 Fixes & Changes
- Fixed: scheduled syncs running “invisibly” – they now refresh Insights and appear in Recent syncs just like manual runs.
- Fixed: Jellyfin and Emby server-level whitelisting. This wasnt correctly implemented as it was using folder ID's and not Library ID's. Fixed now.
- Fixed: Emby Watcher no longer disappears when server IDs are wrong.
- Fixed: Settings screen no longer cuts off the bottom buttons on smaller windows.
- Fixed: “Not connected to Plex” showing even when Plex was already configured in the scrobbler/ watcher section.
- Change: better settings hydrating, sometimes /api/config settings where not hydrated and needed UI refresh
- Change: Watcher Start button stays disabled until Plex/Emby and the selected sink (Trakt / SIMKL) are properly connected.
- Change: Webhook logs stay visible and consistent when debug logging is on.
- Change: Pair library selector now respects server-level whitelists and clearly shows which libraries are selected.
- Change: Fallback code removed from Plex module; be sure to configure your Plex settings correctly.
- Change: Added two additions to maintenance, reset currently playing and Restart CrossWatch (restart container)
- Change: Empty pairs (no features) are now properly skipped in the orchestrator. Also added a warning in the pair-config that no features are enabled...
- Change: Added a /scripts/ folder where I’ll stash utility scripts, like Emby/Jellyfin cleanup tools.
- Change: Added configuration status dots in Authentication Providers (green neon pulse when configured)
From 0.4.x onward I’ll be phasing out a lot of the “safety” fallback code that used to make CrossWatch less user-proof. That means it’s now extra important to actually read the WIKI before using CrossWatch, so your setup matches how the app is meant to be used.
- Pair‑aware Analyzer backend focused on unsynced items with classification (missing_peer, missing_ids, etc.)
- Pair strip UI for selecting specific source⇄target pairs and scoped issue views
- Improved issue detail panel with best‑effort explanations and provider‑specific suggestions
Full changelog
CrossWatch – v0.3.9
Analyzer has been improved and rewritten to be more helpful in finding issues. It now focuses on items that have not been synced and surfaces best-effort reasons why. It still can’t magically restore missing items for every setup, but Analyzer should at least point you in the right direction and give you concrete ideas on what to fix. I’m happy to help users with CrossWatch bugs (crashes, failed runs, weird planner output), but I just can’t support to hunt down every missing item in everyone’s libraries. That’s exactly why Analyzer exists: it gives you a focused list of unsynced items plus likely root causes so you can fix IDs and metadata in Plex/Jellyfin/Emby/Trakt/Simkl/mdblist yourself.
What’s new
-
Analyzer backend rewritten.
- Fresh
/api/analyzer/*stack focused on unsynced items instead of generic counts. - Problems now classify:
missing_peer— item exists at source but not at any active target pair.missing_ids/key_missing_ids/key_ids_mismatch/invalid_id_format.
- Pairs, features and enabled modes are taken into account, so “issues” are pair-aware.
- Fresh
-
Pair-aware Analyzer UI.
- New pair strip at the top:
PLEX ⇄ JELLYFIN,PLEX → SIMKL,PLEX → MDBLIST,PLEX → TRAKT, etc. - Clicking a chip limits the grid and issues to only that pair’s scope.
- Scope toggle:
Scope: issues→ only items withmissing_peerfor active pairs.Scope: all→ all items instate.jsonwithin the selected pairs.
- New pair strip at the top:
-
Better issue detail panel.
- For each issue, Analyzer shows:
- Provider, feature, title/year/type.
- A best-effort explanation of what’s likely wrong and where to fix it (Plex/Jellyfin/Emby vs Trakt/Simkl/mdblist).
- Suggestions pulled from:
- Peers (same title/year/type).
- TMDB external IDs and search.
- Trakt search (de-emphasised when only Trakt data is available).
- Extra hints for language / alt-title mismatches on media servers (e.g. Dutch vs English episode titles) when IDs look fine but peers still fail.
- For each issue, Analyzer shows:
-
Manual ID editing inside Analyzer.
- New “Manual IDs” block per item with inline fields for:
imdb,tmdb,tvdb,trakt,plex,simkl,emby,mdblist.
Save IDs:- Normalises values (e.g.
tt1234567, numeric TMDB/TVDB/etc). - Optionally rekeys the item based on IDs.
- Re-evaluates pair presence so the item can drop out of the issues list after a fix.
- Normalises values (e.g.
Resetrestores the original IDs fromstate.jsonfor that item.
- New “Manual IDs” block per item with inline fields for:
-
Cleaner grid and footer.
- Pair-filtered item list: if you select
PLEX → MDBLIST, the grid shows only items relevant for that pair. - Compact footer with a quick overview per provider, e.g.:
PLEX 1.4k | JF 1.3k | SIMKL 2 | MDB 2 | TRAKT 2. - Split-pane between list and issue detail is resizable again and remembered per browser.
- Pair-filtered item list: if you select
Fixes
-
False positives reduced.
- Missing-peer detection now respects:
- Enabled pairs only.
- Direction and feature (history/watchlist/ratings).
- Items with peers on some targets but not others are scoped correctly instead of being flagged everywhere.
- Missing-peer detection now respects:
-
Stale suggestion mismatches reduced.
- Suggestions are deduplicated on ID signature, so TMDB/Trakt/peer candidates that resolve to the same IDs are collapsed into a single line.
- Trakt-only hits no longer dominate results when better TMDB/peer IDs are available.
-
Ignore flag respected.
- Items with
_ignore_missing_peerset in state are excluded frommissing_peerproblems and from Analyzer’s issues view.
- Items with
If Analyzer still shows a lot of “missing peer” items after this release, you probably have real ID gaps now instead of Analyzer mismatches.
CrossWatch – v0.3.8
Plex & Jellyfin history got better
What’s new
- Episode-accurate writes to Plex. When syncing from Jellyfin, episode events now resolve to the episode ratingKey, not the show, so only the intended episode is marked watched.
- Presence cache for Jellyfin. A short-lived blackbox presence TTL prevents re-planning items that are already watched on Jellyfin, so follow-up runs don’t try to re-add the same history.
- Cleaner follow-up runs. After a successful write, subsequent runs treat those items as present, reducing noise and making “0 adds” the norm when you’re in sync.
Fixes
- Plex normalization from episodes. Provider→Plex now normalizes TV-Shows from episode context, avoiding accidental show-level scrobbles when only an episode was watched.
- Safer scrobble guard. Plex scrobbling is restricted to
episode/movietypes; show containers are ignored. - Jellyfin snapshot stability. History snapshot merges recent “shadow” writes and TTL-bounded presence hints, eliminating repeat add attempts and planner churn.
- Skip semantics clarified. “Skipped” in apply logs means “already present on the destination.” Subsequent runs won’t keep planning those items.
Configuration
- No breaking changes.
- Optional:
blackbox_presence_ttl_seconds(Jellyfin) defaults to 900s if unset.
No manual reset required. If you want a clean slate for testing, you can clear .cw_state/*history.* shadow/blackbox files.
CrossWatch – v0.3.7
Ratings sync is smarter and safer. SIMKL scopes are now enforced automatically.
What’s new
- Rating Season toggle For some strange reason i did not include the season rating toggle, so you can also sync seasons now.
- Provider-aware ratings scope. When SIMKL is in a pair, Seasons and Episodes are auto-disabled and greyed out in the Ratings panel.
- SIMKL ratings feel instant. We now remember recent SIMKL rating writes for a short window (“shadow”), so the next run sees them immediately.
- Trakt season/episode compatibility. Ratings payloads for Trakt now use only the IDs Trakt accepts per type, so your writes go through cleanly.
Fixes
- False mappings into SIMKL. Prevented by scoping (Seasons/Episodes blocked for SIMKL) and stricter ID handling during writes.
- *Ratings delta “no-op” runs. Updates were missed when caches/watermarks didn’t advance; this is corrected and recent changes are detected.
- Trakt “not accepted” on seasons/episodes. Sanitized IDs per type, avoiding server rejections.
- Ratings UI clarity. Scope toggles reflect provider capability; disabled items are visibly greyed out to avoid confusion.
No configuration changes required.
CrossWatch – v0.3.6
Instant whitelist toggles (Jellyfin & Plex) and MDBList show-ratings are now supported.
What’s new
- MDBList: TV show ratings sync. CrossWatch now writes show-level ratings to MDBList. Season/episode ratings still work as before.
- Immediate feedback in Settings. Clicking a whitelist item in Plex and/or Jellyfin now updates instantly and syncs the hidden fields.
Fixes
- MDBList ‘shows’ were skipped. Upstream API bug is fixed;
- MDBList Rating feature is enabled again.
- Whitelist Selections not visible for Plex/Jellyfin. Matrix repaints after each toggle; .
- Master toggles out of sync. Recomputed after every change (also when filters are applied).
No configuration changes required.
CrossWatch – v0.3.5
Important: MDBList Ratings currently do not sync TV (shows/episodes). Movies work. Until we finish the deeper dive, disable MDBList Ratings and use Watchlist only.
What’s new
- Analyzer: MDBList included for ID resolution.
- Exporter: MDBList added as an output/source.
Changes
- Added MDBList to Analyzer so IDs resolve correctly.
- Added MDBList to Exporter.
CrossWatch – v0.3.4
Whoop,whoop.....new provider is added.
New tracker (Experimental): MDBList to sync your Watchlist and Ratings.
Early access: APIs/behavior may change; expect a few rough edges.
What’s new
- MDBList provider
- Watchlist sync (add/remove) and Ratings sync (1–10), one- or two-way.
- Works alongside Trakt/SIMKL and your media servers (Plex/Jellyfin/Emby).
- TMDb/IMDb first for writes; TVDb supported for reads/normalization.
- UI integration
- New Authentication → MDBList panel (Verify, Save, Disconnect).
- Shows Connected when a valid API key is present.
- Added MDBList badge in the features list.
- Engine & health
- Snapshot indexing with progress ticks, rate-limit aware requests, and health probe.
Heads-up: MDBList does not support episodes for ratings. Only movies and shows.
What is MDBList?
MDBList is a smart list builder for movies & TV. It lets you:
- Create auto-updating lists using flexible rules (genres, years, keywords, runtime, country/network, streaming availability).
- Blend scores from multiple sources (IMDb, TMDb, Rotten Tomatoes, Metacritic, Letterboxd, MyAnimeList) and sort by popularity/trending.
- Sync/publish lists to Trakt, feed them to Radarr/Sonarr/Stremio.
- ....and much more...
CrossWatch – v0.3.3
Plex → Trakt scrobbling now uses the same TMDb/Trakt-first strategy as v0.3.2 (Jellyfin webhook).
No more TVDB-only failures from Plex webhooks.
What’s new
- TMDb/Trakt-first resolution: We now prioritize TMDb and IMDb from Plex GUIDs and only fall back to TVDB if needed.
- Show+S/E fallback: When an episode ID can’t be resolved yet, we build the Trakt body with show ids + season/episode numbers so newly aired items still scrobble.
- 404 rescue: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb/TVDB to fetch the correct Trakt ID, then replay the scrobble.
- Broader Plex GUID parsing: We read IDs from multiple places Plex sends them (
guid,grandparentGuid,parentGuid,Guid[]), improving match rates across agents.
Fixes
- TVDB-only scrobbles from Plex failing: Resolved by translating TVDB to Trakt/TMDb before sending, with a rescue path on 404.
- Episodes missing direct episode IDs: Covered by show+season/episode fallback so scrobble bodies remain valid.
- Inconsistent GUID formats: Handled by expanded parsing across all Plex GUID locations.
No config changes required.
CrossWatch – v0.3.2
Jellyfin → Trakt scrobbling for new episodes is improved.
TMDb/Trakt-first ID strategy (no more TVDB-only failures).
Smarter Jellyfin payload parsing (better S/E + ID extraction).
What’s new
- Show+S/E fallback: If an episode id isn’t resolvable yet, we build the Trakt body with the show ids + season/episode numbers (clean path for newly-aired items).
- Rescue on 404: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb to fetch the right Trakt id, then replay the scrobble.
- Broader Jellyfin field support: We now read IDs and S/E from more places Jellyfin sends them:
Provider_tmdb/imdb/tvdb,SeriesProviderIds,SeriesTmdbId/SeriesImdbId/SeriesTvdbId, plus root-level season/episode.
Fixes
- **“.Starts/pauses/stops from Jellyfin now scrobble even when TVDB lags behind.
- 404 on
/scrobble/startor/pausefrom Jellyfin: Resolved by using TMDb/Trakt-first resolution and the rescue path. - Missing S/E numbers when only on the root payload: We now read season/episode from both the item and the root, so the scrobble body is always valid.
No config changes required. Optional: set Jellyfin’s TV metadata provider to TheMovieDB for the smoothest ID mapping.
CrossWatch – v0.3.1
Watcher now supports SIMKL. SIMKL is my personal preferred tracker.
Dual-sink scrobbling: send playback to SIMKL, Trakt, or both, your call.
What’s new
- SIMKL as a Watcher sink: Real-time scrobbling from Plex or Emby to SIMKL (movies & episodes). Pick SIMKL, Trakt, or SIMKL+Trakt in Settings → Scrobble → Watcher.
- Runs alongside Trakt: If you choose both, CrossWatch sends the same play/pause/stop to SIMKL and Trakt in one go.
- Simple setup: Enable Watcher, pick Plex or Emby, choose your Sink, done. Your choice is saved and used on the next run.
How to use
- Open Settings → Scrobble → Watcher.
- Toggle Enable and choose Provider (Plex or Emby).
- Set Sink to SIMKL, Trakt, or SIMKL+Trakt.
- (Optional) Turn on Autostart on boot.
Make sure your SIMKL account is connected under Authentication first.
More info: https://github.com/cenodude/CrossWatch/wiki/Watcher
CrossWatch – v0.3.0
Watchlist sync: is now consistent both ways across Plex, Trakt, and SIMKL — adds and deletes propagate cleanly in the same run.**
Big internal code cleanup: of the pairing engine to reduce “stuck” items and accidental removals.
SIMKL Sync MOD: updated to version 1.0.0
What’s new
- True two-way flow across multiple pairs: Remove or add on any side (Plex/Trakt/SIMKL) and the change is reflected everywhere, even when you run separate pairs in one run.
- Fresh index after writes: After we add/remove on a destination, we immediately refresh that destination so the next pair in the run “sees” the new state.
- SIMKL snapshot smarts: Automatic full refresh when the cache looks stale; otherwise fast incremental updates. Fixes the “SIMKL still shows an old item count” issue.
- Safer delete rules: An item is only deleted if it previously existed on that destination and was observed as removed at the source. This avoids cross-pair false deletes.
- One-way parity: One-way sync benefits from the same safeguards (fresh-after-write visibility, safer deletes, and unresolved tracking) as two-way.
Fixes
- Observed deletes: provider-aware. If a provider can’t report deletions, we don’t invent them. We log it and keep your lists intact.
- Trakt confirmations edge case: Handles the “HTTP 200 but 0 confirmed” scenario more clearly and tracks unresolved state correctly.
- No blocklists on watchlist adds: Blocklists continue to apply to History/Ratings, not Watchlists.
No config changes required. If strange things happens, reset you state in Maintenance.
The order of your PAIRS are important when using multiple two-way syncs pairs with the same Source or Destination.
- Episode-accurate writes to Plex using the episode ratingKey
- Jellyfin short‑lived blackbox presence TTL prevents re‑planning watched items
- Cleaner follow‑up runs treat already‑present items as present
Full changelog
CrossWatch – v0.3.8
Plex & Jellyfin history got better
What’s new
- Episode-accurate writes to Plex. When syncing from Jellyfin, episode events now resolve to the episode ratingKey, not the show, so only the intended episode is marked watched.
- Presence cache for Jellyfin. A short-lived blackbox presence TTL prevents re-planning items that are already watched on Jellyfin, so follow-up runs don’t try to re-add the same history.
- Cleaner follow-up runs. After a successful write, subsequent runs treat those items as present, reducing noise and making “0 adds” the norm when you’re in sync.
Fixes
- Plex normalization from episodes. Provider→Plex now normalizes TV-Shows from episode context, avoiding accidental show-level scrobbles when only an episode was watched.
- Safer scrobble guard. Plex scrobbling is restricted to
episode/movietypes; show containers are ignored. - Jellyfin snapshot stability. History snapshot merges recent “shadow” writes and TTL-bounded presence hints, eliminating repeat add attempts and planner churn.
- Skip semantics clarified. “Skipped” in apply logs means “already present on the destination.” Subsequent runs won’t keep planning those items.
Configuration
- No breaking changes.
- Optional:
blackbox_presence_ttl_seconds(Jellyfin) defaults to 900s if unset.
No manual reset required. If you want a clean slate for testing, you can clear .cw_state/*history.* shadow/blackbox files.
CrossWatch – v0.3.7
Ratings sync is smarter and safer. SIMKL scopes are now enforced automatically.
What’s new
- Rating Season toggle For some strange reason i did not include the season rating toggle, so you can also sync seasons now.
- Provider-aware ratings scope. When SIMKL is in a pair, Seasons and Episodes are auto-disabled and greyed out in the Ratings panel.
- SIMKL ratings feel instant. We now remember recent SIMKL rating writes for a short window (“shadow”), so the next run sees them immediately.
- Trakt season/episode compatibility. Ratings payloads for Trakt now use only the IDs Trakt accepts per type, so your writes go through cleanly.
Fixes
- False mappings into SIMKL. Prevented by scoping (Seasons/Episodes blocked for SIMKL) and stricter ID handling during writes.
- *Ratings delta “no-op” runs. Updates were missed when caches/watermarks didn’t advance; this is corrected and recent changes are detected.
- Trakt “not accepted” on seasons/episodes. Sanitized IDs per type, avoiding server rejections.
- Ratings UI clarity. Scope toggles reflect provider capability; disabled items are visibly greyed out to avoid confusion.
No configuration changes required.
CrossWatch – v0.3.6
Instant whitelist toggles (Jellyfin & Plex) and MDBList show-ratings are now supported.
What’s new
- MDBList: TV show ratings sync. CrossWatch now writes show-level ratings to MDBList. Season/episode ratings still work as before.
- Immediate feedback in Settings. Clicking a whitelist item in Plex and/or Jellyfin now updates instantly and syncs the hidden fields.
Fixes
- MDBList ‘shows’ were skipped. Upstream API bug is fixed;
- MDBList Rating feature is enabled again.
- Whitelist Selections not visible for Plex/Jellyfin. Matrix repaints after each toggle; .
- Master toggles out of sync. Recomputed after every change (also when filters are applied).
No configuration changes required.
CrossWatch – v0.3.5
Important: MDBList Ratings currently do not sync TV (shows/episodes). Movies work. Until we finish the deeper dive, disable MDBList Ratings and use Watchlist only.
What’s new
- Analyzer: MDBList included for ID resolution.
- Exporter: MDBList added as an output/source.
Changes
- Added MDBList to Analyzer so IDs resolve correctly.
- Added MDBList to Exporter.
CrossWatch – v0.3.4
Whoop,whoop.....new provider is added.
New tracker (Experimental): MDBList to sync your Watchlist and Ratings.
Early access: APIs/behavior may change; expect a few rough edges.
What’s new
- MDBList provider
- Watchlist sync (add/remove) and Ratings sync (1–10), one- or two-way.
- Works alongside Trakt/SIMKL and your media servers (Plex/Jellyfin/Emby).
- TMDb/IMDb first for writes; TVDb supported for reads/normalization.
- UI integration
- New Authentication → MDBList panel (Verify, Save, Disconnect).
- Shows Connected when a valid API key is present.
- Added MDBList badge in the features list.
- Engine & health
- Snapshot indexing with progress ticks, rate-limit aware requests, and health probe.
Heads-up: MDBList does not support episodes for ratings. Only movies and shows.
What is MDBList?
MDBList is a smart list builder for movies & TV. It lets you:
- Create auto-updating lists using flexible rules (genres, years, keywords, runtime, country/network, streaming availability).
- Blend scores from multiple sources (IMDb, TMDb, Rotten Tomatoes, Metacritic, Letterboxd, MyAnimeList) and sort by popularity/trending.
- Sync/publish lists to Trakt, feed them to Radarr/Sonarr/Stremio.
- ....and much more...
CrossWatch – v0.3.3
Plex → Trakt scrobbling now uses the same TMDb/Trakt-first strategy as v0.3.2 (Jellyfin webhook).
No more TVDB-only failures from Plex webhooks.
What’s new
- TMDb/Trakt-first resolution: We now prioritize TMDb and IMDb from Plex GUIDs and only fall back to TVDB if needed.
- Show+S/E fallback: When an episode ID can’t be resolved yet, we build the Trakt body with show ids + season/episode numbers so newly aired items still scrobble.
- 404 rescue: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb/TVDB to fetch the correct Trakt ID, then replay the scrobble.
- Broader Plex GUID parsing: We read IDs from multiple places Plex sends them (
guid,grandparentGuid,parentGuid,Guid[]), improving match rates across agents.
Fixes
- TVDB-only scrobbles from Plex failing: Resolved by translating TVDB to Trakt/TMDb before sending, with a rescue path on 404.
- Episodes missing direct episode IDs: Covered by show+season/episode fallback so scrobble bodies remain valid.
- Inconsistent GUID formats: Handled by expanded parsing across all Plex GUID locations.
No config changes required.
CrossWatch – v0.3.2
Jellyfin → Trakt scrobbling for new episodes is improved.
TMDb/Trakt-first ID strategy (no more TVDB-only failures).
Smarter Jellyfin payload parsing (better S/E + ID extraction).
What’s new
- Show+S/E fallback: If an episode id isn’t resolvable yet, we build the Trakt body with the show ids + season/episode numbers (clean path for newly-aired items).
- Rescue on 404: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb to fetch the right Trakt id, then replay the scrobble.
- Broader Jellyfin field support: We now read IDs and S/E from more places Jellyfin sends them:
Provider_tmdb/imdb/tvdb,SeriesProviderIds,SeriesTmdbId/SeriesImdbId/SeriesTvdbId, plus root-level season/episode.
Fixes
- **“.Starts/pauses/stops from Jellyfin now scrobble even when TVDB lags behind.
- 404 on
/scrobble/startor/pausefrom Jellyfin: Resolved by using TMDb/Trakt-first resolution and the rescue path. - Missing S/E numbers when only on the root payload: We now read season/episode from both the item and the root, so the scrobble body is always valid.
No config changes required. Optional: set Jellyfin’s TV metadata provider to TheMovieDB for the smoothest ID mapping.
CrossWatch – v0.3.1
Watcher now supports SIMKL. SIMKL is my personal preferred tracker.
Dual-sink scrobbling: send playback to SIMKL, Trakt, or both, your call.
What’s new
- SIMKL as a Watcher sink: Real-time scrobbling from Plex or Emby to SIMKL (movies & episodes). Pick SIMKL, Trakt, or SIMKL+Trakt in Settings → Scrobble → Watcher.
- Runs alongside Trakt: If you choose both, CrossWatch sends the same play/pause/stop to SIMKL and Trakt in one go.
- Simple setup: Enable Watcher, pick Plex or Emby, choose your Sink, done. Your choice is saved and used on the next run.
How to use
- Open Settings → Scrobble → Watcher.
- Toggle Enable and choose Provider (Plex or Emby).
- Set Sink to SIMKL, Trakt, or SIMKL+Trakt.
- (Optional) Turn on Autostart on boot.
Make sure your SIMKL account is connected under Authentication first.
More info: https://github.com/cenodude/CrossWatch/wiki/Watcher
CrossWatch – v0.3.0
Watchlist sync: is now consistent both ways across Plex, Trakt, and SIMKL — adds and deletes propagate cleanly in the same run.**
Big internal code cleanup: of the pairing engine to reduce “stuck” items and accidental removals.
SIMKL Sync MOD: updated to version 1.0.0
What’s new
- True two-way flow across multiple pairs: Remove or add on any side (Plex/Trakt/SIMKL) and the change is reflected everywhere, even when you run separate pairs in one run.
- Fresh index after writes: After we add/remove on a destination, we immediately refresh that destination so the next pair in the run “sees” the new state.
- SIMKL snapshot smarts: Automatic full refresh when the cache looks stale; otherwise fast incremental updates. Fixes the “SIMKL still shows an old item count” issue.
- Safer delete rules: An item is only deleted if it previously existed on that destination and was observed as removed at the source. This avoids cross-pair false deletes.
- One-way parity: One-way sync benefits from the same safeguards (fresh-after-write visibility, safer deletes, and unresolved tracking) as two-way.
Fixes
- Observed deletes: provider-aware. If a provider can’t report deletions, we don’t invent them. We log it and keep your lists intact.
- Trakt confirmations edge case: Handles the “HTTP 200 but 0 confirmed” scenario more clearly and tracks unresolved state correctly.
- No blocklists on watchlist adds: Blocklists continue to apply to History/Ratings, not Watchlists.
No config changes required. If strange things happens, reset you state in Maintenance.
The order of your PAIRS are important when using multiple two-way syncs pairs with the same Source or Destination.
- Rating Season toggle enables syncing season‑level ratings
- Provider‑aware ratings scope auto‑disables Seasons/Episodes for SIMKL
- Shadow cache makes SIMKL rating writes feel instant
Full changelog
CrossWatch – v0.3.7
Ratings sync is smarter and safer. SIMKL scopes are now enforced automatically.
What’s new
- Rating Season toggle For some strange reason i did not include the season rating toggle, so you can also sync seasons now.
- Provider-aware ratings scope. When SIMKL is in a pair, Seasons and Episodes are auto-disabled and greyed out in the Ratings panel.
- SIMKL ratings feel instant. We now remember recent SIMKL rating writes for a short window (“shadow”), so the next run sees them immediately.
- Trakt season/episode compatibility. Ratings payloads for Trakt now use only the IDs Trakt accepts per type, so your writes go through cleanly.
Fixes
- False mappings into SIMKL. Prevented by scoping (Seasons/Episodes blocked for SIMKL) and stricter ID handling during writes.
- *Ratings delta “no-op” runs. Updates were missed when caches/watermarks didn’t advance; this is corrected and recent changes are detected.
- Trakt “not accepted” on seasons/episodes. Sanitized IDs per type, avoiding server rejections.
- Ratings UI clarity. Scope toggles reflect provider capability; disabled items are visibly greyed out to avoid confusion.
No configuration changes required.
CrossWatch – v0.3.6
Instant whitelist toggles (Jellyfin & Plex) and MDBList show-ratings are now supported.
What’s new
- MDBList: TV show ratings sync. CrossWatch now writes show-level ratings to MDBList. Season/episode ratings still work as before.
- Immediate feedback in Settings. Clicking a whitelist item in Plex and/or Jellyfin now updates instantly and syncs the hidden fields.
Fixes
- MDBList ‘shows’ were skipped. Upstream API bug is fixed;
- MDBList Rating feature is enabled again.
- Whitelist Selections not visible for Plex/Jellyfin. Matrix repaints after each toggle; .
- Master toggles out of sync. Recomputed after every change (also when filters are applied).
No configuration changes required.
CrossWatch – v0.3.5
Important: MDBList Ratings currently do not sync TV (shows/episodes). Movies work. Until we finish the deeper dive, disable MDBList Ratings and use Watchlist only.
What’s new
- Analyzer: MDBList included for ID resolution.
- Exporter: MDBList added as an output/source.
Changes
- Added MDBList to Analyzer so IDs resolve correctly.
- Added MDBList to Exporter.
CrossWatch – v0.3.4
Whoop,whoop.....new provider is added.
New tracker (Experimental): MDBList to sync your Watchlist and Ratings.
Early access: APIs/behavior may change; expect a few rough edges.
What’s new
- MDBList provider
- Watchlist sync (add/remove) and Ratings sync (1–10), one- or two-way.
- Works alongside Trakt/SIMKL and your media servers (Plex/Jellyfin/Emby).
- TMDb/IMDb first for writes; TVDb supported for reads/normalization.
- UI integration
- New Authentication → MDBList panel (Verify, Save, Disconnect).
- Shows Connected when a valid API key is present.
- Added MDBList badge in the features list.
- Engine & health
- Snapshot indexing with progress ticks, rate-limit aware requests, and health probe.
Heads-up: MDBList does not support episodes for ratings. Only movies and shows.
What is MDBList?
MDBList is a smart list builder for movies & TV. It lets you:
- Create auto-updating lists using flexible rules (genres, years, keywords, runtime, country/network, streaming availability).
- Blend scores from multiple sources (IMDb, TMDb, Rotten Tomatoes, Metacritic, Letterboxd, MyAnimeList) and sort by popularity/trending.
- Sync/publish lists to Trakt, feed them to Radarr/Sonarr/Stremio.
- ....and much more...
CrossWatch – v0.3.3
Plex → Trakt scrobbling now uses the same TMDb/Trakt-first strategy as v0.3.2 (Jellyfin webhook).
No more TVDB-only failures from Plex webhooks.
What’s new
- TMDb/Trakt-first resolution: We now prioritize TMDb and IMDb from Plex GUIDs and only fall back to TVDB if needed.
- Show+S/E fallback: When an episode ID can’t be resolved yet, we build the Trakt body with show ids + season/episode numbers so newly aired items still scrobble.
- 404 rescue: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb/TVDB to fetch the correct Trakt ID, then replay the scrobble.
- Broader Plex GUID parsing: We read IDs from multiple places Plex sends them (
guid,grandparentGuid,parentGuid,Guid[]), improving match rates across agents.
Fixes
- TVDB-only scrobbles from Plex failing: Resolved by translating TVDB to Trakt/TMDb before sending, with a rescue path on 404.
- Episodes missing direct episode IDs: Covered by show+season/episode fallback so scrobble bodies remain valid.
- Inconsistent GUID formats: Handled by expanded parsing across all Plex GUID locations.
No config changes required.
CrossWatch – v0.3.2
Jellyfin → Trakt scrobbling for new episodes is improved.
TMDb/Trakt-first ID strategy (no more TVDB-only failures).
Smarter Jellyfin payload parsing (better S/E + ID extraction).
What’s new
- Show+S/E fallback: If an episode id isn’t resolvable yet, we build the Trakt body with the show ids + season/episode numbers (clean path for newly-aired items).
- Rescue on 404: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb to fetch the right Trakt id, then replay the scrobble.
- Broader Jellyfin field support: We now read IDs and S/E from more places Jellyfin sends them:
Provider_tmdb/imdb/tvdb,SeriesProviderIds,SeriesTmdbId/SeriesImdbId/SeriesTvdbId, plus root-level season/episode.
Fixes
- **“.Starts/pauses/stops from Jellyfin now scrobble even when TVDB lags behind.
- 404 on
/scrobble/startor/pausefrom Jellyfin: Resolved by using TMDb/Trakt-first resolution and the rescue path. - Missing S/E numbers when only on the root payload: We now read season/episode from both the item and the root, so the scrobble body is always valid.
No config changes required. Optional: set Jellyfin’s TV metadata provider to TheMovieDB for the smoothest ID mapping.
CrossWatch – v0.3.1
Watcher now supports SIMKL. SIMKL is my personal preferred tracker.
Dual-sink scrobbling: send playback to SIMKL, Trakt, or both, your call.
What’s new
- SIMKL as a Watcher sink: Real-time scrobbling from Plex or Emby to SIMKL (movies & episodes). Pick SIMKL, Trakt, or SIMKL+Trakt in Settings → Scrobble → Watcher.
- Runs alongside Trakt: If you choose both, CrossWatch sends the same play/pause/stop to SIMKL and Trakt in one go.
- Simple setup: Enable Watcher, pick Plex or Emby, choose your Sink, done. Your choice is saved and used on the next run.
How to use
- Open Settings → Scrobble → Watcher.
- Toggle Enable and choose Provider (Plex or Emby).
- Set Sink to SIMKL, Trakt, or SIMKL+Trakt.
- (Optional) Turn on Autostart on boot.
Make sure your SIMKL account is connected under Authentication first.
More info: https://github.com/cenodude/CrossWatch/wiki/Watcher
CrossWatch – v0.3.0
Watchlist sync: is now consistent both ways across Plex, Trakt, and SIMKL — adds and deletes propagate cleanly in the same run.**
Big internal code cleanup: of the pairing engine to reduce “stuck” items and accidental removals.
SIMKL Sync MOD: updated to version 1.0.0
What’s new
- True two-way flow across multiple pairs: Remove or add on any side (Plex/Trakt/SIMKL) and the change is reflected everywhere, even when you run separate pairs in one run.
- Fresh index after writes: After we add/remove on a destination, we immediately refresh that destination so the next pair in the run “sees” the new state.
- SIMKL snapshot smarts: Automatic full refresh when the cache looks stale; otherwise fast incremental updates. Fixes the “SIMKL still shows an old item count” issue.
- Safer delete rules: An item is only deleted if it previously existed on that destination and was observed as removed at the source. This avoids cross-pair false deletes.
- One-way parity: One-way sync benefits from the same safeguards (fresh-after-write visibility, safer deletes, and unresolved tracking) as two-way.
Fixes
- Observed deletes: provider-aware. If a provider can’t report deletions, we don’t invent them. We log it and keep your lists intact.
- Trakt confirmations edge case: Handles the “HTTP 200 but 0 confirmed” scenario more clearly and tracks unresolved state correctly.
- No blocklists on watchlist adds: Blocklists continue to apply to History/Ratings, not Watchlists.
No config changes required. If strange things happens, reset you state in Maintenance.
The order of your PAIRS are important when using multiple two-way syncs pairs with the same Source or Destination.
- MDBList now writes show‑level ratings (TV shows) to the service; season/episode ratings continue as before.
- Instant feedback in Settings: toggling a whitelist item for Plex or Jellyfin updates immediately and syncs hidden fields.
Full changelog
CrossWatch – v0.3.6
Instant whitelist toggles (Jellyfin & Plex) and MDBList show-ratings are now supported.
What’s new
- MDBList: TV show ratings sync. CrossWatch now writes show-level ratings to MDBList. Season/episode ratings still work as before.
- Immediate feedback in Settings. Clicking a whitelist item in Plex and/or Jellyfin now updates instantly and syncs the hidden fields.
Fixes
- MDBList ‘shows’ were skipped. Upstream API bug is fixed;
- MDBList Rating feature is enabled again.
- Whitelist Selections not visible for Plex/Jellyfin. Matrix repaints after each toggle; .
- Master toggles out of sync. Recomputed after every change (also when filters are applied).
No configuration changes required.
CrossWatch – v0.3.5
Important: MDBList Ratings currently do not sync TV (shows/episodes). Movies work. Until we finish the deeper dive, disable MDBList Ratings and use Watchlist only.
What’s new
- Analyzer: MDBList included for ID resolution.
- Exporter: MDBList added as an output/source.
Changes
- Added MDBList to Analyzer so IDs resolve correctly.
- Added MDBList to Exporter.
CrossWatch – v0.3.4
Whoop,whoop.....new provider is added.
New tracker (Experimental): MDBList to sync your Watchlist and Ratings.
Early access: APIs/behavior may change; expect a few rough edges.
What’s new
- MDBList provider
- Watchlist sync (add/remove) and Ratings sync (1–10), one- or two-way.
- Works alongside Trakt/SIMKL and your media servers (Plex/Jellyfin/Emby).
- TMDb/IMDb first for writes; TVDb supported for reads/normalization.
- UI integration
- New Authentication → MDBList panel (Verify, Save, Disconnect).
- Shows Connected when a valid API key is present.
- Added MDBList badge in the features list.
- Engine & health
- Snapshot indexing with progress ticks, rate-limit aware requests, and health probe.
Heads-up: MDBList does not support episodes for ratings. Only movies and shows.
What is MDBList?
MDBList is a smart list builder for movies & TV. It lets you:
- Create auto-updating lists using flexible rules (genres, years, keywords, runtime, country/network, streaming availability).
- Blend scores from multiple sources (IMDb, TMDb, Rotten Tomatoes, Metacritic, Letterboxd, MyAnimeList) and sort by popularity/trending.
- Sync/publish lists to Trakt, feed them to Radarr/Sonarr/Stremio.
- ....and much more...
CrossWatch – v0.3.3
Plex → Trakt scrobbling now uses the same TMDb/Trakt-first strategy as v0.3.2 (Jellyfin webhook).
No more TVDB-only failures from Plex webhooks.
What’s new
- TMDb/Trakt-first resolution: We now prioritize TMDb and IMDb from Plex GUIDs and only fall back to TVDB if needed.
- Show+S/E fallback: When an episode ID can’t be resolved yet, we build the Trakt body with show ids + season/episode numbers so newly aired items still scrobble.
- 404 rescue: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb/TVDB to fetch the correct Trakt ID, then replay the scrobble.
- Broader Plex GUID parsing: We read IDs from multiple places Plex sends them (
guid,grandparentGuid,parentGuid,Guid[]), improving match rates across agents.
Fixes
- TVDB-only scrobbles from Plex failing: Resolved by translating TVDB to Trakt/TMDb before sending, with a rescue path on 404.
- Episodes missing direct episode IDs: Covered by show+season/episode fallback so scrobble bodies remain valid.
- Inconsistent GUID formats: Handled by expanded parsing across all Plex GUID locations.
No config changes required.
CrossWatch – v0.3.2
Jellyfin → Trakt scrobbling for new episodes is improved.
TMDb/Trakt-first ID strategy (no more TVDB-only failures).
Smarter Jellyfin payload parsing (better S/E + ID extraction).
What’s new
- Show+S/E fallback: If an episode id isn’t resolvable yet, we build the Trakt body with the show ids + season/episode numbers (clean path for newly-aired items).
- Rescue on 404: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb to fetch the right Trakt id, then replay the scrobble.
- Broader Jellyfin field support: We now read IDs and S/E from more places Jellyfin sends them:
Provider_tmdb/imdb/tvdb,SeriesProviderIds,SeriesTmdbId/SeriesImdbId/SeriesTvdbId, plus root-level season/episode.
Fixes
- **“.Starts/pauses/stops from Jellyfin now scrobble even when TVDB lags behind.
- 404 on
/scrobble/startor/pausefrom Jellyfin: Resolved by using TMDb/Trakt-first resolution and the rescue path. - Missing S/E numbers when only on the root payload: We now read season/episode from both the item and the root, so the scrobble body is always valid.
No config changes required. Optional: set Jellyfin’s TV metadata provider to TheMovieDB for the smoothest ID mapping.
CrossWatch – v0.3.1
Watcher now supports SIMKL. SIMKL is my personal preferred tracker.
Dual-sink scrobbling: send playback to SIMKL, Trakt, or both, your call.
What’s new
- SIMKL as a Watcher sink: Real-time scrobbling from Plex or Emby to SIMKL (movies & episodes). Pick SIMKL, Trakt, or SIMKL+Trakt in Settings → Scrobble → Watcher.
- Runs alongside Trakt: If you choose both, CrossWatch sends the same play/pause/stop to SIMKL and Trakt in one go.
- Simple setup: Enable Watcher, pick Plex or Emby, choose your Sink, done. Your choice is saved and used on the next run.
How to use
- Open Settings → Scrobble → Watcher.
- Toggle Enable and choose Provider (Plex or Emby).
- Set Sink to SIMKL, Trakt, or SIMKL+Trakt.
- (Optional) Turn on Autostart on boot.
Make sure your SIMKL account is connected under Authentication first.
More info: https://github.com/cenodude/CrossWatch/wiki/Watcher
CrossWatch – v0.3.0
Watchlist sync: is now consistent both ways across Plex, Trakt, and SIMKL — adds and deletes propagate cleanly in the same run.**
Big internal code cleanup: of the pairing engine to reduce “stuck” items and accidental removals.
SIMKL Sync MOD: updated to version 1.0.0
What’s new
- True two-way flow across multiple pairs: Remove or add on any side (Plex/Trakt/SIMKL) and the change is reflected everywhere, even when you run separate pairs in one run.
- Fresh index after writes: After we add/remove on a destination, we immediately refresh that destination so the next pair in the run “sees” the new state.
- SIMKL snapshot smarts: Automatic full refresh when the cache looks stale; otherwise fast incremental updates. Fixes the “SIMKL still shows an old item count” issue.
- Safer delete rules: An item is only deleted if it previously existed on that destination and was observed as removed at the source. This avoids cross-pair false deletes.
- One-way parity: One-way sync benefits from the same safeguards (fresh-after-write visibility, safer deletes, and unresolved tracking) as two-way.
Fixes
- Observed deletes: provider-aware. If a provider can’t report deletions, we don’t invent them. We log it and keep your lists intact.
- Trakt confirmations edge case: Handles the “HTTP 200 but 0 confirmed” scenario more clearly and tracks unresolved state correctly.
- No blocklists on watchlist adds: Blocklists continue to apply to History/Ratings, not Watchlists.
No config changes required. If strange things happens, reset you state in Maintenance.
The order of your PAIRS are important when using multiple two-way syncs pairs with the same Source or Destination.
- Show+S/E fallback when episode ID is unresolved
- Auto‑retry rescue on 404 by searching TMDb/IMDb for the Trakt ID
- Broader Jellyfin field support reading Provider IDs and root S/E
Full changelog
CrossWatch – v0.3.2
Jellyfin → Trakt scrobbling for new episodes is improved.
TMDb/Trakt-first ID strategy (no more TVDB-only failures).
Smarter Jellyfin payload parsing (better S/E + ID extraction).
What’s new
- Show+S/E fallback: If an episode id isn’t resolvable yet, we build the Trakt body with the show ids + season/episode numbers (clean path for newly-aired items).
- Rescue on 404: If Trakt returns 404, we auto-retry by searching the episode via TMDb/IMDb to fetch the right Trakt id, then replay the scrobble.
- Broader Jellyfin field support: We now read IDs and S/E from more places Jellyfin sends them:
Provider_tmdb/imdb/tvdb,SeriesProviderIds,SeriesTmdbId/SeriesImdbId/SeriesTvdbId, plus root-level season/episode.
Fixes
- **“.Starts/pauses/stops from Jellyfin now scrobble even when TVDB lags behind.
- 404 on
/scrobble/startor/pausefrom Jellyfin: Resolved by using TMDb/Trakt-first resolution and the rescue path. - Missing S/E numbers when only on the root payload: We now read season/episode from both the item and the root, so the scrobble body is always valid.
No config changes required. Optional: set Jellyfin’s TV metadata provider to TheMovieDB for the smoothest ID mapping.
CrossWatch – v0.3.1
Watcher now supports SIMKL. SIMKL is my personal preferred tracker.
Dual-sink scrobbling: send playback to SIMKL, Trakt, or both, your call.
What’s new
- SIMKL as a Watcher sink: Real-time scrobbling from Plex or Emby to SIMKL (movies & episodes). Pick SIMKL, Trakt, or SIMKL+Trakt in Settings → Scrobble → Watcher.
- Runs alongside Trakt: If you choose both, CrossWatch sends the same play/pause/stop to SIMKL and Trakt in one go.
- Simple setup: Enable Watcher, pick Plex or Emby, choose your Sink, done. Your choice is saved and used on the next run.
How to use
- Open Settings → Scrobble → Watcher.
- Toggle Enable and choose Provider (Plex or Emby).
- Set Sink to SIMKL, Trakt, or SIMKL+Trakt.
- (Optional) Turn on Autostart on boot.
Make sure your SIMKL account is connected under Authentication first.
More info: https://github.com/cenodude/CrossWatch/wiki/Watcher
CrossWatch – v0.3.0
Watchlist sync: is now consistent both ways across Plex, Trakt, and SIMKL — adds and deletes propagate cleanly in the same run.**
Big internal code cleanup: of the pairing engine to reduce “stuck” items and accidental removals.
SIMKL Sync MOD: updated to version 1.0.0
What’s new
- True two-way flow across multiple pairs: Remove or add on any side (Plex/Trakt/SIMKL) and the change is reflected everywhere, even when you run separate pairs in one run.
- Fresh index after writes: After we add/remove on a destination, we immediately refresh that destination so the next pair in the run “sees” the new state.
- SIMKL snapshot smarts: Automatic full refresh when the cache looks stale; otherwise fast incremental updates. Fixes the “SIMKL still shows an old item count” issue.
- Safer delete rules: An item is only deleted if it previously existed on that destination and was observed as removed at the source. This avoids cross-pair false deletes.
- One-way parity: One-way sync benefits from the same safeguards (fresh-after-write visibility, safer deletes, and unresolved tracking) as two-way.
Fixes
- Observed deletes: provider-aware. If a provider can’t report deletions, we don’t invent them. We log it and keep your lists intact.
- Trakt confirmations edge case: Handles the “HTTP 200 but 0 confirmed” scenario more clearly and tracks unresolved state correctly.
- No blocklists on watchlist adds: Blocklists continue to apply to History/Ratings, not Watchlists.
No config changes required. If strange things happens, reset you state in Maintenance.
The order of your PAIRS are important when using multiple two-way syncs pairs with the same Source or Destination.
- SIMKL added as a Watcher sink for real‑time scrobbling of Plex/Emby movies and episodes
- Dual‑sink mode allows sending playback to SIMKL, Trakt, or both simultaneously
Full changelog
CrossWatch – v0.3.1
Watcher now supports SIMKL. SIMKL is my personal preferred tracker.
Dual-sink scrobbling: send playback to SIMKL, Trakt, or both, your call.
What’s new
- SIMKL as a Watcher sink: Real-time scrobbling from Plex or Emby to SIMKL (movies & episodes). Pick SIMKL, Trakt, or SIMKL+Trakt in Settings → Scrobble → Watcher.
- Runs alongside Trakt: If you choose both, CrossWatch sends the same play/pause/stop to SIMKL and Trakt in one go.
- Simple setup: Enable Watcher, pick Plex or Emby, choose your Sink, done. Your choice is saved and used on the next run.
How to use
- Open Settings → Scrobble → Watcher.
- Toggle Enable and choose Provider (Plex or Emby).
- Set Sink to SIMKL, Trakt, or SIMKL+Trakt.
- (Optional) Turn on Autostart on boot.
Make sure your SIMKL account is connected under Authentication first.
More info: https://github.com/cenodude/CrossWatch/wiki/Watcher
CrossWatch – v0.3.0
Watchlist sync: is now consistent both ways across Plex, Trakt, and SIMKL — adds and deletes propagate cleanly in the same run.**
Big internal code cleanup: of the pairing engine to reduce “stuck” items and accidental removals.
SIMKL Sync MOD: updated to version 1.0.0
What’s new
- True two-way flow across multiple pairs: Remove or add on any side (Plex/Trakt/SIMKL) and the change is reflected everywhere, even when you run separate pairs in one run.
- Fresh index after writes: After we add/remove on a destination, we immediately refresh that destination so the next pair in the run “sees” the new state.
- SIMKL snapshot smarts: Automatic full refresh when the cache looks stale; otherwise fast incremental updates. Fixes the “SIMKL still shows an old item count” issue.
- Safer delete rules: An item is only deleted if it previously existed on that destination and was observed as removed at the source. This avoids cross-pair false deletes.
- One-way parity: One-way sync benefits from the same safeguards (fresh-after-write visibility, safer deletes, and unresolved tracking) as two-way.
Fixes
- Observed deletes: provider-aware. If a provider can’t report deletions, we don’t invent them. We log it and keep your lists intact.
- Trakt confirmations edge case: Handles the “HTTP 200 but 0 confirmed” scenario more clearly and tracks unresolved state correctly.
- No blocklists on watchlist adds: Blocklists continue to apply to History/Ratings, not Watchlists.
No config changes required. If strange things happens, reset you state in Maintenance.
The order of your PAIRS are important when using multiple two-way syncs pairs with the same Source or Destination.
- Order of PAIRS matters for multiple two‑way syncs sharing the same source or destination; ensure correct ordering to avoid unexpected behavior.
- If issues arise, use Maintenance mode to reset state.
- True two‑way flow across multiple pairs (add/remove on any side propagates everywhere in a single run)
- Fresh index after writes: destinations are refreshed immediately so subsequent pairs see the new state
- SIMKL snapshot smarts: automatic full refresh when cache is stale, otherwise incremental updates
Full changelog
CrossWatch – v0.3.0
Watchlist sync: is now more consistent with cross-pairs across Plex, Trakt, and SIMKL, adds and deletes propagate cleanly in the same run.**
Big internal code cleanup: of the pairing (orchestrator) engine to reduce “stuck” items.
SIMKL Sync MOD: updated to version 1.0.0
What’s new
- True two-way flow across multiple pairs: Remove or add on any side (Plex/Trakt/SIMKL) and the change is reflected everywhere, even when you run separate pairs in one run.
- Fresh index after writes: After we add/remove on a destination, we immediately refresh that destination so the next pair in the run “sees” the new state.
- SIMKL snapshot smarts: Automatic full refresh when the cache looks stale; otherwise fast incremental updates. Fixes the “SIMKL still shows an old item count” issue.
- Safer delete rules: An item is only deleted if it previously existed on that destination and was observed as removed at the source. This avoids cross-pair false deletes.
- One-way parity: One-way sync benefits from the same safeguards (fresh-after-write visibility, safer deletes, and unresolved tracking) as two-way.
Fixes
- Observed deletes: provider-aware. If a provider can’t report deletions, We log it and keep your lists intact.
- No blocklists on watchlist adds: Blocklists continue to apply to History/Ratings, not Watchlists.
No config changes required. If strange things happens, reset you state in Maintenance.
The order of your PAIRS are important when using multiple two-way syncs pairs with the same Source or Destination.
- Per‑item session keys prevent cross‑item bleed during continuous playback
- Stronger ID resolution with nested Provider IDs and episode rescue lookup (IMDb/TMDb/TVDb → Trakt)
Full changelog
CrossWatch – v0.2.20
Webhook Jellyfin → Trakt scrobbling fix and fewer false starts.
What’s new
- **Real pause/resume from Jellyfin
- Cleaner session tracking: Per-item session keys prevent cross-item bleed during continuous play.
- Stronger ID resolution: Uses nested Provider IDs; episode “rescue” lookup (IMDb/TMDb/TVDb → Trakt) when needed.
Fixes
- No more STOP→START at the end: Late STOPs no longer misfire as STARTs; demotion/promotion logic corrected.
- Pause debouncing: Rapid toggles won’t spam Trakt; duplicate STOPs are suppressed.
- Progress sanity: Regression clamp tuned; 100% “late starts” are suppressed; username parsing more compatible.
Recommended Jellyfin webhook events
Enable: Playback Start, Playback Stop, Playback Progress
https://github.com/cenodude/CrossWatch/wiki/Webhook
_No breaking changes. Existing configs keep working.
CrossWatch – v0.2.19
Small update: some Watcher improvements
What’s new
- Finish detection:
complete_athonored — PAUSE/STOP ≥complete_atorforce_stop_atmarks watched. - Watch mode dials:
pause_debounce_seconds+suppress_start_atnow applied (Advanced settings)
Fixes
- 409 check-in: auto-clear and proceed if Trakt reports watched.
CrossWatch – v0.2.18
Webhook and Watcher improvements Safer “finished” detection, fewer noisy logs, and watchlist auto-remove happens for the types you allow.
Explaination about Plex autoplay quarantine: when you skip credits, Plex’s autoplay pops up and after few sec. the next episode will play...BUT Plex doesn’t fire a new webhook play event.
As a result, Trakt shows nothing in “Now Playing” (it’ll only mark it watched at the end or when you pause/play).
Autoplay quarantine will wait a few seconds, checks in your PMS if the next episode is really playing, then sends one clean start to Trakt.
"Now Playing" works in Trakt without the need to do pause/play. Tiny quality-of-life win, but it’s there and can be disabled if you dont like it.
Please note that this is a webhook only issue, the watcher is already realtime and therefore doesnt need Plex quarantine.
✨ What’s new
Watchlist auto-remove
- Auto-remove now runs after a confirmed finish for the types you allow
- Plex/Jellyfin/Emby webhooks no longer try to remove items themselves. One brain, zero double-deletes.
Respect your content types
- Auto-remove obeys your allowed types:
- Default is movies only.
- Shows/episodes are removed only if you enable those types.
- For episodes, we clean up using show-level IDs (how most watchlists store TV).
🔧 Fixes & changes
- 409 Conflict (active check-in) is handled: we clear Trakt’s
/checkinand retry. If Trakt still says it’s watched, we proceed to auto-remove once finished. - Backoff for 429/5xx stays in place; tokens refresh automatically on 401.
- Cleaner logs: watchers log short event summaries; the Trakt sink logs the final user/action line. Deep details live in DEBUG only.
- UI improvement: Added user selection and user_id filtering and automatically hydrate from your config.
Result: finish a movie (or show/episode if allowed), and it’s removed from your connected watchlists—once, correctly.
CrossWatch – v0.2.17
Small fix but important: Plex Watchlist no longer stops at 20. We now fetch everything.
🚀 What changed
- Full watchlist, every time. Proper pagination with
X-Plex-Container-Start/Size+offset/limitandtotalSize. - More reliable reads. We prefer JSON from Plex Discover so we don’t lose paging info.
- Clear progress. Logs now show
index size,raw,coll, andtypesfor quick sanity checks.
🧪 Notes for power users
- Page size defaults to 100. You can optionally set
plex.watchlist_page_sizeif you want to tune it. - If you see
coll > 0, Plex returned duplicates; we collapse them by canonical key on purpose.
CrossWatch – v0.2.16
Webhooks got a big glow-up (Plex, Jellyfin, Emby). Not gonna lie: making webhooks behave is extremely tricky. The Watcher? Way simpler.
The catch with webhooks is we only get what your media server sends—and Plex keeps things a bit… ehmmm...minimal.
That’s where credits-skip and “auto play next” from Plex like to mess things up.
Note: For Webhooks; my Jellyfin testing is limited, and I can’t test Emby at all (no Emby Premiere). I’m primarily a Plex user.
Recommended advanced webhook settings: set Stop→Pause threshold to 85% and Force stop to 95%.
✨ What’s new
“Media server knows best”
- Plex:
media.scrobble(threshold/credits) is treated as authoritative — we finish at ≥95% so Trakt marks watched even if offsets look tiny after credits-skip. - Jellyfin & Emby: If the payload/UserData indicates Played/Watched (or
PlayCount> 0 / “ItemMarkedAsPlayed”), we treat it as authoritative and finish at ≥95%. Manual “Mark as played” now reliably reflects on Trakt.
Plex autoplay quarantine (new)
- After a STOP at ≥95%, if a new episode autostarts quickly, we quarantine the start.
- After
suppress_autoplay_seconds(default 15s), we probeGET /status/sessionsand:- If the player is playing the quarantined item → we send a normal start.
- If not playing → we clear quarantine (no accidental scrobble).
- New Plex-only config:
suppress_autoplay_seconds: default 15. Set this a few seconds above your Plex autoplay countdown. For a 10-second countdown, use 13–15s.probe_session_progress: default true (corrects bogus % via/status/sessionswhen credits are skipped).
Trakt-first, safer ID strategy
- Prefer ids.trakt; for episodes, fall back to show.ids + S/E.
- Adds episode GUID search rescue (
/search/{imdb|tvdb|tmdb}type=episode) when Trakt returns 404.
Smarter end-of-item behavior
- Rewatch-aware regression clamp: prevents % from jumping backwards, but correctly resets on a fresh (re)start/new session.
- Pause @ ~100% clamp: pauses that report 100% clamp to ≥95% so STOP cleanly completes as watched.
- Demote suspicious STOPs (e.g., sudden jumps from low % → 98%) to PAUSE unless thresholds met.
- Debounce rapid STOP/PAUSE spam to avoid noisy or duplicate calls.
🔧 Fixes & Changes
- Trakt 409 checkin conflicts auto-resolved by clearing
/checkinand retrying. - Backoff on 429/5xx responses.
- Consistent defaults:
force_stop_at95 across Plex/Jellyfin/Emby;stop_pause_thresholdstays 80. - Cross-provider Watchlist auto-remove triggers on STOP ≥95%.
- Cleaner logs: clear “intent → response” lines, quarantine probes, and ID resolution.
CrossWatch – v0.2.15
Yesterday I taught CrossWatch a new trick: finish a movie and poof it gets kicked off your Plex watchlist.
Then I thought, “why only for plex?” I have all the logics in-place... Well, now it works across all your media servers AND trackers.
Also squashed a issue where deleted items could boomerang back in depending on your sync pairs. Not anymore.
Two flies, one swatter: broader support AND that reappearing-item is gone.
Anyways, i hope you enjoy it.
✨ What’s new
Auto-remove finished movies from ALL your Watchlists
- When you finish a movie in Plex/Emby/Jellyfin, CrossWatch can automatically remove it from your all your Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in filtering
- Enable Auto-remove from Watchlists
- Make sure your watchlists are syncing between your media servers and trackers as the magic depends based on your state.json.
That’s it: finish a movie in Plex, Jellyfin or Emby and zap, it disappears from your Watchlist once you’re done.
🔧 Fixes & Changes
- Finishing a movie now registers more reliably using webhook/watcher on Trakt, even if you just let it play through the credits.
- CrossWatch keeps a lower profile while it’s working.
- Jellyfin/Emby webhooks now follow the same start/pause/stop smarts as Plex.
- One simple line per action in the UI logs (no duplicates, less noise).
- Small fixes and polish across webhooks and watcher.
CrossWatch – v0.2.14
Plex doesn’t auto-remove movies you’ve finished from your Watchlist. CrossWatch now does.
✨ What’s new
Auto-remove finished movies from your Plex Watchlist
- When you finish a movie in Plex, CrossWatch can automatically remove it from your Plex Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in Plex filtering
- Enable Auto-remove from Plex Watchlist
That’s it—watch a movie in Plex, and it disappears from your Watchlist once you’re essentially done.
If you also use two-way sync, that other service might add it back. So keep track on it!
🔧 Also improved Webhooks
- Clearer episode titles (now shows display like Show Name S02E04 — Episode Title).
- Smoother start/pause/stop detection with fewer duplicate updates.
- Smarter matching to the right movie/show.
- General polish and small fixes.
--
CrossWatch – v0.2.13
Exporter is now available. Export your state.json (Watchlist/History/Ratings) to CSV for various services.
It’s a nice-to-have—handy when needed—but remember: CrossWatch is a synchronizer, not a media tracker.
✨ Highlights
Export CSV files with the new Exporter
- Open Exporter (next to Analyzer).
- Pick your Provider (Trakt, Plex, Emby, Jellyfin, SIMKL).
- Pick What to export: Watchlist, History, or Ratings.
- Pick Where it’s going: Letterboxd, IMDb, JustWatch, Yamtrack, or TMDB.
- Use Search (title / id / year) to filter.
- Toggle Select all (filtered) or tick items one-by-one; the counter shows how many you’ll export.
- Click Export — done.
https://github.com/cenodude/CrossWatch/wiki/Exporter
🔧 Fixes & Changes
- UI save fixes fixed an issue where some provider settings weren’t saved to config.json
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Back up `/config` before upgrade.
- Remove the existing config directory after stopping CrossWatch and re‑configure on first run.
- Verify all provider tokens and library scopes in Settings after starting the new version.
- FastAPI‑based router architecture for speed and reliability
- New scheduling modes (hourly, every N hours, daily with timezone support)
- Improved progress bar that no longer jumps prematurely
Full changelog
CrossWatch – v0.2.19
Small update: some Watcher improvements
What’s new
- Finish detection:
complete_athonored — PAUSE/STOP ≥complete_atorforce_stop_atmarks watched. - Watch mode dials:
pause_debounce_seconds+suppress_start_atnow applied (Advanced settings)
Fixes
- 409 check-in: auto-clear and proceed if Trakt reports watched.
CrossWatch – v0.2.18
Webhook and Watcher improvements Safer “finished” detection, fewer noisy logs, and watchlist auto-remove happens for the types you allow.
Explaination about Plex autoplay quarantine: when you skip credits, Plex’s autoplay pops up and after few sec. the next episode will play...BUT Plex doesn’t fire a new webhook play event.
As a result, Trakt shows nothing in “Now Playing” (it’ll only mark it watched at the end or when you pause/play).
Autoplay quarantine will wait a few seconds, checks in your PMS if the next episode is really playing, then sends one clean start to Trakt.
"Now Playing" works in Trakt without the need to do pause/play. Tiny quality-of-life win, but it’s there and can be disabled if you dont like it.
Please note that this is a webhook only issue, the watcher is already realtime and therefore doesnt need Plex quarantine.
✨ What’s new
Watchlist auto-remove
- Auto-remove now runs after a confirmed finish for the types you allow
- Plex/Jellyfin/Emby webhooks no longer try to remove items themselves. One brain, zero double-deletes.
Respect your content types
- Auto-remove obeys your allowed types:
- Default is movies only.
- Shows/episodes are removed only if you enable those types.
- For episodes, we clean up using show-level IDs (how most watchlists store TV).
🔧 Fixes & changes
- 409 Conflict (active check-in) is handled: we clear Trakt’s
/checkinand retry. If Trakt still says it’s watched, we proceed to auto-remove once finished. - Backoff for 429/5xx stays in place; tokens refresh automatically on 401.
- Cleaner logs: watchers log short event summaries; the Trakt sink logs the final user/action line. Deep details live in DEBUG only.
- UI improvement: Added user selection and user_id filtering and automatically hydrate from your config.
Result: finish a movie (or show/episode if allowed), and it’s removed from your connected watchlists—once, correctly.
CrossWatch – v0.2.17
Small fix but important: Plex Watchlist no longer stops at 20. We now fetch everything.
🚀 What changed
- Full watchlist, every time. Proper pagination with
X-Plex-Container-Start/Size+offset/limitandtotalSize. - More reliable reads. We prefer JSON from Plex Discover so we don’t lose paging info.
- Clear progress. Logs now show
index size,raw,coll, andtypesfor quick sanity checks.
🧪 Notes for power users
- Page size defaults to 100. You can optionally set
plex.watchlist_page_sizeif you want to tune it. - If you see
coll > 0, Plex returned duplicates; we collapse them by canonical key on purpose.
CrossWatch – v0.2.16
Webhooks got a big glow-up (Plex, Jellyfin, Emby). Not gonna lie: making webhooks behave is extremely tricky. The Watcher? Way simpler.
The catch with webhooks is we only get what your media server sends—and Plex keeps things a bit… ehmmm...minimal.
That’s where credits-skip and “auto play next” from Plex like to mess things up.
Note: For Webhooks; my Jellyfin testing is limited, and I can’t test Emby at all (no Emby Premiere). I’m primarily a Plex user.
Recommended advanced webhook settings: set Stop→Pause threshold to 85% and Force stop to 95%.
✨ What’s new
“Media server knows best”
- Plex:
media.scrobble(threshold/credits) is treated as authoritative — we finish at ≥95% so Trakt marks watched even if offsets look tiny after credits-skip. - Jellyfin & Emby: If the payload/UserData indicates Played/Watched (or
PlayCount> 0 / “ItemMarkedAsPlayed”), we treat it as authoritative and finish at ≥95%. Manual “Mark as played” now reliably reflects on Trakt.
Plex autoplay quarantine (new)
- After a STOP at ≥95%, if a new episode autostarts quickly, we quarantine the start.
- After
suppress_autoplay_seconds(default 15s), we probeGET /status/sessionsand:- If the player is playing the quarantined item → we send a normal start.
- If not playing → we clear quarantine (no accidental scrobble).
- New Plex-only config:
suppress_autoplay_seconds: default 15. Set this a few seconds above your Plex autoplay countdown. For a 10-second countdown, use 13–15s.probe_session_progress: default true (corrects bogus % via/status/sessionswhen credits are skipped).
Trakt-first, safer ID strategy
- Prefer ids.trakt; for episodes, fall back to show.ids + S/E.
- Adds episode GUID search rescue (
/search/{imdb|tvdb|tmdb}type=episode) when Trakt returns 404.
Smarter end-of-item behavior
- Rewatch-aware regression clamp: prevents % from jumping backwards, but correctly resets on a fresh (re)start/new session.
- Pause @ ~100% clamp: pauses that report 100% clamp to ≥95% so STOP cleanly completes as watched.
- Demote suspicious STOPs (e.g., sudden jumps from low % → 98%) to PAUSE unless thresholds met.
- Debounce rapid STOP/PAUSE spam to avoid noisy or duplicate calls.
🔧 Fixes & Changes
- Trakt 409 checkin conflicts auto-resolved by clearing
/checkinand retrying. - Backoff on 429/5xx responses.
- Consistent defaults:
force_stop_at95 across Plex/Jellyfin/Emby;stop_pause_thresholdstays 80. - Cross-provider Watchlist auto-remove triggers on STOP ≥95%.
- Cleaner logs: clear “intent → response” lines, quarantine probes, and ID resolution.
CrossWatch – v0.2.15
Yesterday I taught CrossWatch a new trick: finish a movie and poof it gets kicked off your Plex watchlist.
Then I thought, “why only for plex?” I have all the logics in-place... Well, now it works across all your media servers AND trackers.
Also squashed a issue where deleted items could boomerang back in depending on your sync pairs. Not anymore.
Two flies, one swatter: broader support AND that reappearing-item is gone.
Anyways, i hope you enjoy it.
✨ What’s new
Auto-remove finished movies from ALL your Watchlists
- When you finish a movie in Plex/Emby/Jellyfin, CrossWatch can automatically remove it from your all your Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in filtering
- Enable Auto-remove from Watchlists
- Make sure your watchlists are syncing between your media servers and trackers as the magic depends based on your state.json.
That’s it: finish a movie in Plex, Jellyfin or Emby and zap, it disappears from your Watchlist once you’re done.
🔧 Fixes & Changes
- Finishing a movie now registers more reliably using webhook/watcher on Trakt, even if you just let it play through the credits.
- CrossWatch keeps a lower profile while it’s working.
- Jellyfin/Emby webhooks now follow the same start/pause/stop smarts as Plex.
- One simple line per action in the UI logs (no duplicates, less noise).
- Small fixes and polish across webhooks and watcher.
CrossWatch – v0.2.14
Plex doesn’t auto-remove movies you’ve finished from your Watchlist. CrossWatch now does.
✨ What’s new
Auto-remove finished movies from your Plex Watchlist
- When you finish a movie in Plex, CrossWatch can automatically remove it from your Plex Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in Plex filtering
- Enable Auto-remove from Plex Watchlist
That’s it—watch a movie in Plex, and it disappears from your Watchlist once you’re essentially done.
If you also use two-way sync, that other service might add it back. So keep track on it!
🔧 Also improved Webhooks
- Clearer episode titles (now shows display like Show Name S02E04 — Episode Title).
- Smoother start/pause/stop detection with fewer duplicate updates.
- Smarter matching to the right movie/show.
- General polish and small fixes.
--
CrossWatch – v0.2.13
Exporter is now available. Export your state.json (Watchlist/History/Ratings) to CSV for various services.
It’s a nice-to-have—handy when needed—but remember: CrossWatch is a synchronizer, not a media tracker.
✨ Highlights
Export CSV files with the new Exporter
- Open Exporter (next to Analyzer).
- Pick your Provider (Trakt, Plex, Emby, Jellyfin, SIMKL).
- Pick What to export: Watchlist, History, or Ratings.
- Pick Where it’s going: Letterboxd, IMDb, JustWatch, Yamtrack, or TMDB.
- Use Search (title / id / year) to filter.
- Toggle Select all (filtered) or tick items one-by-one; the counter shows how many you’ll export.
- Click Export — done.
https://github.com/cenodude/CrossWatch/wiki/Exporter
🔧 Fixes & Changes
- UI save fixes fixed an issue where some provider settings weren’t saved to config.json
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Webhook improvements: safer finished detection, enhanced logging
- Watchlist auto-remove runs after confirmed finish for user‑selected content types
Full changelog
CrossWatch – v0.2.18
Webhook and Watcher improvements Safer “finished” detection, better logs, and watchlist auto-remove happens for the types you allow.
Explaination about Plex autoplay quarantine: when you skip credits, Plex’s autoplay pops up and after few sec. the next episode will play...BUT Plex doesn’t fire a new webhook play event.
As a result, Trakt shows nothing in “Now Playing” (it’ll only mark it watched at the end or when you pause/play).
Autoplay quarantine will wait a few seconds, checks in your PMS if the next episode is really playing, then sends one clean start to Trakt.
"Now Playing" works in Trakt without the need to do pause/play. Tiny quality-of-life win, but it’s there and can be disabled if you dont like it.
Please note that this is a webhook only issue, the watcher is already realtime and therefore doesnt need Plex quarantine.
✨ What’s new
Watchlist auto-remove
- Auto-remove now runs after a confirmed finish for the types you allow
- Plex/Jellyfin/Emby webhooks no longer try to remove items themselves. One brain, zero double-deletes.
Respect your content types
- Auto-remove obeys your allowed types:
- Default is movies only.
- Shows/episodes are removed only if you enable those types.
- For episodes, we clean up using show-level IDs (how most watchlists store TV).
🔧 Fixes & changes
- 409 Conflict (active check-in) is handled: we clear Trakt’s
/checkinand retry. If Trakt still says it’s watched, we proceed to auto-remove once finished. - Backoff for 429/5xx stays in place; tokens refresh automatically on 401.
- Cleaner logs: watchers log short event summaries; the Trakt sink logs the final user/action line. Deep details live in DEBUG only.
- UI improvement: Added user selection and user_id filtering and automatically hydrate from your config.
Result: finish a movie (or show/episode if allowed), and it’s removed from your connected watchlists—once, correctly.
CrossWatch – v0.2.17
Small fix but important: Plex Watchlist no longer stops at 20. We now fetch everything.
🚀 What changed
- Full watchlist, every time. Proper pagination with
X-Plex-Container-Start/Size+offset/limitandtotalSize. - More reliable reads. We prefer JSON from Plex Discover so we don’t lose paging info.
- Clear progress. Logs now show
index size,raw,coll, andtypesfor quick sanity checks.
🧪 Notes for power users
- Page size defaults to 100. You can optionally set
plex.watchlist_page_sizeif you want to tune it. - If you see
coll > 0, Plex returned duplicates; we collapse them by canonical key on purpose.
CrossWatch – v0.2.16
Webhooks got a big glow-up (Plex, Jellyfin, Emby). Not gonna lie: making webhooks behave is extremely tricky. The Watcher? Way simpler.
The catch with webhooks is we only get what your media server sends—and Plex keeps things a bit… ehmmm...minimal.
That’s where credits-skip and “auto play next” from Plex like to mess things up.
Note: For Webhooks; my Jellyfin testing is limited, and I can’t test Emby at all (no Emby Premiere). I’m primarily a Plex user.
Recommended advanced webhook settings: set Stop→Pause threshold to 85% and Force stop to 95%.
✨ What’s new
“Media server knows best”
- Plex:
media.scrobble(threshold/credits) is treated as authoritative — we finish at ≥95% so Trakt marks watched even if offsets look tiny after credits-skip. - Jellyfin & Emby: If the payload/UserData indicates Played/Watched (or
PlayCount> 0 / “ItemMarkedAsPlayed”), we treat it as authoritative and finish at ≥95%. Manual “Mark as played” now reliably reflects on Trakt.
Plex autoplay quarantine (new)
- After a STOP at ≥95%, if a new episode autostarts quickly, we quarantine the start.
- After
suppress_autoplay_seconds(default 15s), we probeGET /status/sessionsand:- If the player is playing the quarantined item → we send a normal start.
- If not playing → we clear quarantine (no accidental scrobble).
- New Plex-only config:
suppress_autoplay_seconds: default 15. Set this a few seconds above your Plex autoplay countdown. For a 10-second countdown, use 13–15s.probe_session_progress: default true (corrects bogus % via/status/sessionswhen credits are skipped).
Trakt-first, safer ID strategy
- Prefer ids.trakt; for episodes, fall back to show.ids + S/E.
- Adds episode GUID search rescue (
/search/{imdb|tvdb|tmdb}type=episode) when Trakt returns 404.
Smarter end-of-item behavior
- Rewatch-aware regression clamp: prevents % from jumping backwards, but correctly resets on a fresh (re)start/new session.
- Pause @ ~100% clamp: pauses that report 100% clamp to ≥95% so STOP cleanly completes as watched.
- Demote suspicious STOPs (e.g., sudden jumps from low % → 98%) to PAUSE unless thresholds met.
- Debounce rapid STOP/PAUSE spam to avoid noisy or duplicate calls.
🔧 Fixes & Changes
- Trakt 409 checkin conflicts auto-resolved by clearing
/checkinand retrying. - Backoff on 429/5xx responses.
- Consistent defaults:
force_stop_at95 across Plex/Jellyfin/Emby;stop_pause_thresholdstays 80. - Cross-provider Watchlist auto-remove triggers on STOP ≥95%.
- Cleaner logs: clear “intent → response” lines, quarantine probes, and ID resolution.
CrossWatch – v0.2.15
Yesterday I taught CrossWatch a new trick: finish a movie and poof it gets kicked off your Plex watchlist.
Then I thought, “why only for plex?” I have all the logics in-place... Well, now it works across all your media servers AND trackers.
Also squashed a issue where deleted items could boomerang back in depending on your sync pairs. Not anymore.
Two flies, one swatter: broader support AND that reappearing-item is gone.
Anyways, i hope you enjoy it.
✨ What’s new
Auto-remove finished movies from ALL your Watchlists
- When you finish a movie in Plex/Emby/Jellyfin, CrossWatch can automatically remove it from your all your Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in filtering
- Enable Auto-remove from Watchlists
- Make sure your watchlists are syncing between your media servers and trackers as the magic depends based on your state.json.
That’s it: finish a movie in Plex, Jellyfin or Emby and zap, it disappears from your Watchlist once you’re done.
🔧 Fixes & Changes
- Finishing a movie now registers more reliably using webhook/watcher on Trakt, even if you just let it play through the credits.
- CrossWatch keeps a lower profile while it’s working.
- Jellyfin/Emby webhooks now follow the same start/pause/stop smarts as Plex.
- One simple line per action in the UI logs (no duplicates, less noise).
- Small fixes and polish across webhooks and watcher.
CrossWatch – v0.2.14
Plex doesn’t auto-remove movies you’ve finished from your Watchlist. CrossWatch now does.
✨ What’s new
Auto-remove finished movies from your Plex Watchlist
- When you finish a movie in Plex, CrossWatch can automatically remove it from your Plex Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in Plex filtering
- Enable Auto-remove from Plex Watchlist
That’s it—watch a movie in Plex, and it disappears from your Watchlist once you’re essentially done.
If you also use two-way sync, that other service might add it back. So keep track on it!
🔧 Also improved Webhooks
- Clearer episode titles (now shows display like Show Name S02E04 — Episode Title).
- Smoother start/pause/stop detection with fewer duplicate updates.
- Smarter matching to the right movie/show.
- General polish and small fixes.
--
CrossWatch – v0.2.13
Exporter is now available. Export your state.json (Watchlist/History/Ratings) to CSV for various services.
It’s a nice-to-have—handy when needed—but remember: CrossWatch is a synchronizer, not a media tracker.
✨ Highlights
Export CSV files with the new Exporter
- Open Exporter (next to Analyzer).
- Pick your Provider (Trakt, Plex, Emby, Jellyfin, SIMKL).
- Pick What to export: Watchlist, History, or Ratings.
- Pick Where it’s going: Letterboxd, IMDb, JustWatch, Yamtrack, or TMDB.
- Use Search (title / id / year) to filter.
- Toggle Select all (filtered) or tick items one-by-one; the counter shows how many you’ll export.
- Click Export — done.
https://github.com/cenodude/CrossWatch/wiki/Exporter
🔧 Fixes & Changes
- UI save fixes fixed an issue where some provider settings weren’t saved to config.json
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Full watchlist retrieval via proper pagination (X-Plex-Container‑Start/Size, offset/limit, totalSize)
- More reliable JSON reads from Plex Discover
- Enhanced log output showing index size, raw data, collection count, and type breakdown
Full changelog
CrossWatch – v0.2.17
Small fix but important: Plex Watchlist no longer stops at 20. We now fetch everything.
🚀 What changed
- Full watchlist, every time. Proper pagination with
X-Plex-Container-Start/Size+offset/limitandtotalSize. - More reliable reads. We prefer JSON from Plex Discover so we don’t lose paging info.
- Clear progress. Logs now show
index size,raw,coll, andtypesfor quick sanity checks.
CrossWatch – v0.2.16
Webhooks got a big glow-up (Plex, Jellyfin, Emby). Not gonna lie: making webhooks behave is extremely tricky. The Watcher? Way simpler.
The catch with webhooks is we only get what your media server sends—and Plex keeps things a bit… ehmmm...minimal.
That’s where credits-skip and “auto play next” from Plex like to mess things up.
Note: For Webhooks; my Jellyfin testing is limited, and I can’t test Emby at all (no Emby Premiere). I’m primarily a Plex user.
Recommended advanced webhook settings: set Stop→Pause threshold to 85% and Force stop to 95%.
✨ What’s new
“Media server knows best”
- Plex:
media.scrobble(threshold/credits) is treated as authoritative — we finish at ≥95% so Trakt marks watched even if offsets look tiny after credits-skip. - Jellyfin & Emby: If the payload/UserData indicates Played/Watched (or
PlayCount> 0 / “ItemMarkedAsPlayed”), we treat it as authoritative and finish at ≥95%. Manual “Mark as played” now reliably reflects on Trakt.
Plex autoplay quarantine (new)
- After a STOP at ≥95%, if a new episode autostarts quickly, we quarantine the start.
- After
suppress_autoplay_seconds(default 15s), we probeGET /status/sessionsand:- If the player is playing the quarantined item → we send a normal start.
- If not playing → we clear quarantine (no accidental scrobble).
- New Plex-only config:
suppress_autoplay_seconds: default 15. Set this a few seconds above your Plex autoplay countdown. For a 10-second countdown, use 13–15s.probe_session_progress: default true (corrects bogus % via/status/sessionswhen credits are skipped).
Trakt-first, safer ID strategy
- Prefer ids.trakt; for episodes, fall back to show.ids + S/E.
- Adds episode GUID search rescue (
/search/{imdb|tvdb|tmdb}type=episode) when Trakt returns 404.
Smarter end-of-item behavior
- Rewatch-aware regression clamp: prevents % from jumping backwards, but correctly resets on a fresh (re)start/new session.
- Pause @ ~100% clamp: pauses that report 100% clamp to ≥95% so STOP cleanly completes as watched.
- Demote suspicious STOPs (e.g., sudden jumps from low % → 98%) to PAUSE unless thresholds met.
- Debounce rapid STOP/PAUSE spam to avoid noisy or duplicate calls.
🔧 Fixes & Changes
- Trakt 409 checkin conflicts auto-resolved by clearing
/checkinand retrying. - Backoff on 429/5xx responses.
- Consistent defaults:
force_stop_at95 across Plex/Jellyfin/Emby;stop_pause_thresholdstays 80. - Cross-provider Watchlist auto-remove triggers on STOP ≥95%.
- Cleaner logs: clear “intent → response” lines, quarantine probes, and ID resolution.
CrossWatch – v0.2.15
Yesterday I taught CrossWatch a new trick: finish a movie and poof it gets kicked off your Plex watchlist.
Then I thought, “why only for plex?” I have all the logics in-place... Well, now it works across all your media servers AND trackers.
Also squashed a issue where deleted items could boomerang back in depending on your sync pairs. Not anymore.
Two flies, one swatter: broader support AND that reappearing-item is gone.
Anyways, i hope you enjoy it.
✨ What’s new
Auto-remove finished movies from ALL your Watchlists
- When you finish a movie in Plex/Emby/Jellyfin, CrossWatch can automatically remove it from your all your Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in filtering
- Enable Auto-remove from Watchlists
- Make sure your watchlists are syncing between your media servers and trackers as the magic depends based on your state.json.
That’s it: finish a movie in Plex, Jellyfin or Emby and zap, it disappears from your Watchlist once you’re done.
🔧 Fixes & Changes
- Finishing a movie now registers more reliably using webhook/watcher on Trakt, even if you just let it play through the credits.
- CrossWatch keeps a lower profile while it’s working.
- Jellyfin/Emby webhooks now follow the same start/pause/stop smarts as Plex.
- One simple line per action in the UI logs (no duplicates, less noise).
- Small fixes and polish across webhooks and watcher.
CrossWatch – v0.2.14
Plex doesn’t auto-remove movies you’ve finished from your Watchlist. CrossWatch now does.
✨ What’s new
Auto-remove finished movies from your Plex Watchlist
- When you finish a movie in Plex, CrossWatch can automatically remove it from your Plex Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in Plex filtering
- Enable Auto-remove from Plex Watchlist
That’s it—watch a movie in Plex, and it disappears from your Watchlist once you’re essentially done.
If you also use two-way sync, that other service might add it back. So keep track on it!
🔧 Also improved Webhooks
- Clearer episode titles (now shows display like Show Name S02E04 — Episode Title).
- Smoother start/pause/stop detection with fewer duplicate updates.
- Smarter matching to the right movie/show.
- General polish and small fixes.
--
CrossWatch – v0.2.13
Exporter is now available. Export your state.json (Watchlist/History/Ratings) to CSV for various services.
It’s a nice-to-have—handy when needed—but remember: CrossWatch is a synchronizer, not a media tracker.
✨ Highlights
Export CSV files with the new Exporter
- Open Exporter (next to Analyzer).
- Pick your Provider (Trakt, Plex, Emby, Jellyfin, SIMKL).
- Pick What to export: Watchlist, History, or Ratings.
- Pick Where it’s going: Letterboxd, IMDb, JustWatch, Yamtrack, or TMDB.
- Use Search (title / id / year) to filter.
- Toggle Select all (filtered) or tick items one-by-one; the counter shows how many you’ll export.
- Click Export — done.
https://github.com/cenodude/CrossWatch/wiki/Exporter
🔧 Fixes & Changes
- UI save fixes fixed an issue where some provider settings weren’t saved to config.json
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Plex autoplay quarantine: after a STOP at ≥95% the system quarantines an immediate start, validates it with /status/sessions after `suppress_autoplay_seconds` (default 15s), and either scrobbles or clears the quarantine.
- New Plex‑only configs `suppress_autoplay_seconds` (default 15) and `probe_session_progress` (default true).
Full changelog
CrossWatch – v0.2.16
Webhooks got a big glow-up (Plex, Jellyfin, Emby). Not gonna lie: making webhooks behave is extremely tricky.
The Watcher? Way simpler. The catch with webhooks is we only get what your media server sends, and Plex keeps things a bit… ehmmm...minimal.
That’s where credits-skip and “auto play next” from Plex like to mess things up.
Note: For Webhooks; my Jellyfin testing is limited, and I can’t test Emby at all (no Emby Premiere). I’m primarily a Plex user.
Recommended advanced webhook settings: set Stop→Pause threshold to 85% and Force stop to 95%.
All values as described below are configurable and are based on the recommended settings:
✨ What’s new
“Media server knows best”
- Plex:
media.scrobble(threshold/credits) is treated as authoritative so we finish at ≥95% so Trakt marks watched even if offsets look tiny after credits-skip. - Jellyfin & Emby: If the payload/UserData indicates Played/Watched (or
PlayCount> 0 / “ItemMarkedAsPlayed”), we treat it as authoritative and finish at ≥95%. Manual “Mark as played” now reliably reflects on Trakt.
Plex autoplay quarantine (new)
- After a STOP at ≥95%, if a new episode autostarts quickly, we quarantine the start.
- After
suppress_autoplay_seconds(default 15s), we probeGET /status/sessionsand:- If the player is playing the quarantined item → we send a normal start.
- If not playing → we clear quarantine (no accidental scrobble).
- New Plex-only config:
suppress_autoplay_seconds: default 15. Set this a few seconds above your Plex autoplay countdown. For a 10-second countdown, use 13–15s.probe_session_progress: default true (corrects bogus % via/status/sessionswhen credits are skipped).
Trakt-first, safer ID strategy
- Prefer ids.trakt; for episodes, fall back to show.ids + S/E.
- Adds episode GUID search rescue (
/search/{imdb|tvdb|tmdb}type=episode) when Trakt returns 404.
Smarter end-of-item behavior
- Rewatch-aware regression clamp: prevents % from jumping backwards, but correctly resets on a fresh (re)start/new session.
- Pause @ ~100% clamp: pauses that report 100% clamp to ≥95% so STOP cleanly completes as watched.
- Demote suspicious STOPs (e.g., sudden jumps from low % → 98%) to PAUSE unless thresholds met.
- Debounce rapid STOP/PAUSE spam to avoid noisy or duplicate calls.
🔧 Fixes & Changes
- Trakt 409 checkin conflicts auto-resolved by clearing
/checkinand retrying. - Backoff on 429/5xx responses.
- Cross-provider Watchlist auto-remove triggers on STOP
- Cleaner logs: clear “intent → response” lines, quarantine probes, and ID resolution.
CrossWatch – v0.2.15
Yesterday I taught CrossWatch a new trick: finish a movie and poof it gets kicked off your Plex watchlist.
Then I thought, “why only for plex?” I have all the logics in-place... Well, now it works across all your media servers AND trackers.
Also squashed a issue where deleted items could boomerang back in depending on your sync pairs. Not anymore.
Two flies, one swatter: broader support AND that reappearing-item is gone.
Anyways, i hope you enjoy it.
✨ What’s new
Auto-remove finished movies from ALL your Watchlists
- When you finish a movie in Plex/Emby/Jellyfin, CrossWatch can automatically remove it from your all your Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in filtering
- Enable Auto-remove from Watchlists
- Make sure your watchlists are syncing between your media servers and trackers as the magic depends based on your state.json.
That’s it: finish a movie in Plex, Jellyfin or Emby and zap, it disappears from your Watchlist once you’re done.
🔧 Fixes & Changes
- Finishing a movie now registers more reliably using webhook/watcher on Trakt, even if you just let it play through the credits.
- CrossWatch keeps a lower profile while it’s working.
- Jellyfin/Emby webhooks now follow the same start/pause/stop smarts as Plex.
- One simple line per action in the UI logs (no duplicates, less noise).
- Small fixes and polish across webhooks and watcher.
CrossWatch – v0.2.14
Plex doesn’t auto-remove movies you’ve finished from your Watchlist. CrossWatch now does.
✨ What’s new
Auto-remove finished movies from your Plex Watchlist
- When you finish a movie in Plex, CrossWatch can automatically remove it from your Plex Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in Plex filtering
- Enable Auto-remove from Plex Watchlist
That’s it—watch a movie in Plex, and it disappears from your Watchlist once you’re essentially done.
If you also use two-way sync, that other service might add it back. So keep track on it!
🔧 Also improved Webhooks
- Clearer episode titles (now shows display like Show Name S02E04 — Episode Title).
- Smoother start/pause/stop detection with fewer duplicate updates.
- Smarter matching to the right movie/show.
- General polish and small fixes.
--
CrossWatch – v0.2.13
Exporter is now available. Export your state.json (Watchlist/History/Ratings) to CSV for various services.
It’s a nice-to-have—handy when needed—but remember: CrossWatch is a synchronizer, not a media tracker.
✨ Highlights
Export CSV files with the new Exporter
- Open Exporter (next to Analyzer).
- Pick your Provider (Trakt, Plex, Emby, Jellyfin, SIMKL).
- Pick What to export: Watchlist, History, or Ratings.
- Pick Where it’s going: Letterboxd, IMDb, JustWatch, Yamtrack, or TMDB.
- Use Search (title / id / year) to filter.
- Toggle Select all (filtered) or tick items one-by-one; the counter shows how many you’ll export.
- Click Export — done.
https://github.com/cenodude/CrossWatch/wiki/Exporter
🔧 Fixes & Changes
- UI save fixes fixed an issue where some provider settings weren’t saved to config.json
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Auto‑remove finished movies from **all** watchlists (Plex/Emby/Jellyfin) with safe defaults and cross‑mode support
- Exporter: CSV export of state.json data for Watchlist, History, Ratings to multiple services
Full changelog
CrossWatch – v0.2.15
Yesterday I taught CrossWatch a new trick: finish a movie and poof it gets kicked off your Plex watchlist.
Then I thought, “why only for plex?” I have all the logics in-place... Well, now it works across all your media servers AND trackers.
Also squashed a issue where deleted items could boomerang back in depending on your sync pairs. Not anymore.
Two flies, one swatter: broader support AND that reappearing-item is gone.
Anyways, i hope you enjoy it.
✨ What’s new
Auto-remove finished movies from ALL your Watchlists
- When you finish a movie in Plex/Emby/Jellyfin, CrossWatch can automatically remove it from your all your Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in filtering
- Enable Auto-remove from Watchlists
- Make sure your watchlists are syncing between your media servers and trackers as the magic depends based on your state.json.
That’s it: finish a movie in Plex, Jellyfin or Emby and zap, it disappears from your Watchlist once you’re done.
🔧 Fixes & Changes
- Finishing a movie now registers more reliably using webhook/watcher on Trakt, even if you just let it play through the credits.
- CrossWatch keeps a lower profile while it’s working.
- Jellyfin/Emby webhooks now follow the same start/pause/stop smarts as Plex.
- One simple line per action in the UI logs (no duplicates, less noise).
- Small fixes and polish across webhooks and watcher.
CrossWatch – v0.2.14
Plex doesn’t auto-remove movies you’ve finished from your Watchlist. CrossWatch now does.
✨ What’s new
Auto-remove finished movies from your Plex Watchlist
- When you finish a movie in Plex, CrossWatch can automatically remove it from your Plex Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in Plex filtering
- Enable Auto-remove from Plex Watchlist
That’s it—watch a movie in Plex, and it disappears from your Watchlist once you’re essentially done.
If you also use two-way sync, that other service might add it back. So keep track on it!
🔧 Also improved Webhooks
- Clearer episode titles (now shows display like Show Name S02E04 — Episode Title).
- Smoother start/pause/stop detection with fewer duplicate updates.
- Smarter matching to the right movie/show.
- General polish and small fixes.
--
CrossWatch – v0.2.13
Exporter is now available. Export your state.json (Watchlist/History/Ratings) to CSV for various services.
It’s a nice-to-have—handy when needed—but remember: CrossWatch is a synchronizer, not a media tracker.
✨ Highlights
Export CSV files with the new Exporter
- Open Exporter (next to Analyzer).
- Pick your Provider (Trakt, Plex, Emby, Jellyfin, SIMKL).
- Pick What to export: Watchlist, History, or Ratings.
- Pick Where it’s going: Letterboxd, IMDb, JustWatch, Yamtrack, or TMDB.
- Use Search (title / id / year) to filter.
- Toggle Select all (filtered) or tick items one-by-one; the counter shows how many you’ll export.
- Click Export — done.
https://github.com/cenodude/CrossWatch/wiki/Exporter
🔧 Fixes & Changes
- UI save fixes fixed an issue where some provider settings weren’t saved to config.json
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Auto‑remove finished movies from Plex Watchlist (off by default, configurable in Settings → Scrobbler/webhook or watcher)
- Clearer episode titles in webhook format (Show Name S02E04 — Episode Title)
- Smoother start/pause/stop detection with reduced duplicate updates
Full changelog
CrossWatch – v0.2.14
Plex doesn’t auto-remove movies you’ve finished from your Watchlist. CrossWatch now does.
✨ What’s new
Auto-remove finished movies from your Plex Watchlist
- When you finish a movie in Plex, CrossWatch can automatically remove it from your Plex Watchlist.
- Works in both CrossWatch modes (webhooks and watcher)
- Safe by default:
- Off until you turn it on
- Only removes movies (not shows)
- Triggers near the end of playback
- Honors your user/server filters and avoids double removals.
✅ How to turn it on
- Go to Settings → Scrobbler / webhook or watcher in Plex filtering
- Enable Auto-remove from Plex Watchlist
That’s it, watch a movie in Plex, and it disappears from your Watchlist once you’re essentially done.
If you also use two-way sync, that other service might add it back. So keep track on it!
Read Wiki [Webhooks] and Watcher
🔧 Also improved Webhooks
- Clearer episode titles (now shows display like Show Name S02E04 — Episode Title).
- Smoother start/pause/stop detection with fewer duplicate updates.
- Smarter matching to the right movie/show.
- General polish and small fixes.
CrossWatch – v0.2.13
Exporter is now available. Export your state.json (Watchlist/History/Ratings) to CSV for various services.
It’s a nice-to-have—handy when needed—but remember: CrossWatch is a synchronizer, not a media tracker.
✨ Highlights
Export CSV files with the new Exporter
- Open Exporter (next to Analyzer).
- Pick your Provider (Trakt, Plex, Emby, Jellyfin, SIMKL).
- Pick What to export: Watchlist, History, or Ratings.
- Pick Where it’s going: Letterboxd, IMDb, JustWatch, Yamtrack, or TMDB.
- Use Search (title / id / year) to filter.
- Toggle Select all (filtered) or tick items one-by-one; the counter shows how many you’ll export.
- Click Export — done.
https://github.com/cenodude/CrossWatch/wiki/Exporter
🔧 Fixes & Changes
- UI save fixes fixed an issue where some provider settings weren’t saved to config.json
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Exporter: Convert Watchlist/History/Ratings from state.json to CSV for Trakt, Plex, Emby, Jellyfin, SIMKL → Letterboxd, IMDb, JustWatch, Yamtrack, TMDB
- One‑click Delete token button for all auth providers (Emby, Jellyfin, Plex, Trakt, SIMKL)
- Smarter empty‑state wizard now hides when sync pairs or Scrobbler are configured
Full changelog
CrossWatch – v0.2.13
Exporter is now available. Export your state.json (Watchlist/History/Ratings) to CSV for various services.
It’s a nice-to-have, handy when needed, but remember: CrossWatch is a synchronizer, not a media tracker.
✨ Highlights
Export CSV files with the new Exporter
- Open Exporter (next to Analyzer).
- Pick your Provider (Trakt, Plex, Emby, Jellyfin, SIMKL).
- Pick What to export: Watchlist, History, or Ratings.
- Pick Where it’s going: Letterboxd, IMDb, JustWatch, Yamtrack, or TMDB.
- Use Search (title / id / year) to filter.
- Toggle Select all (filtered) or tick items one-by-one; the counter shows how many you’ll export.
- Click Export — done.
🔧 Fixes & Changes
- UI save fixes fixed an issue where some provider settings weren’t saved to config.json
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- One-click Delete token button on each auth panel (Emby, Jellyfin, Plex, Trakt, SIMKL)
- Smarter Insights empty-state: wizard hidden when sync pairs exist or Scrobbler is enabled
Full changelog
CrossWatch – v0.2.12
Some auth cleanup, one-click token nukes, and a smarter empty-state, plus some improved Plex Watchlist syncing.
✨ Highlights
One-click Delete token (all providers)
- New Delete button on each auth panel.
- Instantly clears the stored token for Emby, Jellyfin, Plex, Trakt, SIMKL.
Smarter empty-state (Insights)
- The “No synchronization pairs configured” wizard now shows only if:
- you have zero sync pairs AND
- the Scrobbler is not enabled (Webhook/Watcher).
- If you have pairs OR Scrobbler, you won’t see the wizard.
🔧 Plex Watchlist changes
- ID-first resolver (optional, ON by default): tries METADATA.matches with external IDs before doing text search.
- Text search for candidates (ON by default): uses title / slug / year on Plex Discover to collect candidates, then matches by IDs.
- PMS fallback (OFF by default): optional local PMS fallback for add/remove if Discover resolution fails.
- Explicit GUID priority (first hit wins):
tmdb → imdb → tvdb → agent:themoviedb:en → agent:themoviedb → agent:imdb
⚠️ Note about Discover search: Plex Discover does not support direct search by IMDb/TMDB/TVDB IDs. For tricky regional/AKA titles, consider enabling PMS fallback or fixing the match manually on your PMS.
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Upgrade guidance: stop the container, back up `/config`, pull the latest image (`ghcr.io/cenodude/crosswatch:latest`), start it, verify tokens and library scopes, then test one pair before enabling scheduling.
- Added “Drop guard” and associated “Suspect guard (shrinking inventories)” panel with configurable Min previous size and Shrink threshold (%) to protect against accidental mass removals.
Full changelog
CrossWatch – v0.2.11
Trakt Collections
- New “Add collections to Trakt.”
- Trakt collections = titles you have in your library (e.g., Plex/Emby/Jellyfin)
✨ Highlights
Trakt Collections (History)
- Toggle: Pair → History → “Add collections to Trakt.”
Drop guard / Suspect guard (Globals) ùpdated
- Toggle: Pair → Globals → “Drop guard.”
- Purpose: protects against accidental mass removals when a source suddenly reports far fewer items.
🔧 Fixes & Changes
Trakt Watchlist (moved existing options from Providers into the feature)
- Location: Pair → Watchlist → Advanced → Trakt
- Use ETag — Cache-friendly reads.
- Shadow TTL (hours) — Local shadow freshness window (default ~168h).
- Batch size — Control write chunking.
- Log rate limits — Extra visibility when Trakt throttles.
- Freeze details — Don’t churn item details each run.
Trakt History — Unresolved Freeze (moved existing options from Providers into the feature)
- Toggle: Pair History → Advanced → → “Unresolved Freeze.”
- Purpose: park unresolved items so runs don’t keep hammering the same misses.
Trakt Number Fallback (History)
- Toggle: Pair → Advanced → History → “Number Fallback.”
- Uses numbers-form payload when per-episode IDs aren’t available but show IDs and S/E numbers are.
- Reduces resolver calls and avoids mismatches. Off by default.
Drop guard / Suspect guard (Globals)
- Location: Pair → Globals → Drop guard
- When enabled, a Suspect guard (shrinking inventories) panel appears with:
- Min previous size — ignore tiny lists below this size.
- Shrink threshold (%) — mark run suspect when
current_size < (1 − threshold) × previous_size.
- Effect: on a suspect run, bulk removals are blocked and a warning is shown, helping avoid bad deletes after partial reads/outages.
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- SIMKL ↔ Trakt two‑way history sync preserves episode IDs, multiple plays via watched_at timestamps
- Discover queries now handle ampersand/word digit conversion and strip locale parentheses
Full changelog
CrossWatch – v0.2.10
SIMKL to TRAKT and TRAKT to SIMKL history syncs now works
- Great two-way backup/import for SIMKL and Trakt
- Episodes resolve to real episode IDs, less show-ID screwups.
watched_attimestamps preserved, so multiple plays stay intact.- Movies and episodes sync cleanly in both directions.
- To unlock this amazing functionality you’ll need a $5/month subscription… just kidding 😉
- in the future i will add some real backup functionalities, with date, etc for easy restore
The experimental fallback_GUID for Plex worked absolutely like ass, so it needed fixing.
The fallback_guid logic is rather complex, and CrossWatch is basically the only that has this option.
Only enable fallback_guid if you truly need it (though it’s fun seeing ancient Plex items reappear). Heads-up: it can take ages depending on your library size; watch the progress in your container console log… and chilllllllll.
✨ Highlights
-
SIMKL ⇄ TRAKT history sync now works.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
watched_at. - TRAKT → SIMKL: movies and episodes transfer with correct IDs and timestamps.
- BACKUP: great way to backup your data between SIMKL and Trakt.
- SIMKL → TRAKT: episodes are resolved to real episode IDs; multiple plays are preserved via
-
Discover actually finds things again.
Smarter query variants: we now try&↔and, and convert digits 1–9 ↔ words (e.g.,House 1⇄House One).
Also strip locale junk like(NL)or any parentheses before searching (e.g.,Encanto (NL)→Encanto). -
SIMKL/TRAKT mappings restored.
The GUID fallback/enrichment path is back to the old reliability, but with safer checks. -
Plex history sync is sturdier.
Better ratingKey resolution, saner episode heuristics, fewer silent skips, clearer debug logs.
CrossWatch – v0.2.9
History-first release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Emby History → Plex now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes (user‑visible)
Emby — History (destination)
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time (default 300s).
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Back up /config before upgrade.
- After pulling the latest image, re‑verify tokens and library scopes in Settings.
- FastAPI split into lean routers for faster syncs
- Scheduling 2.0 with hourly, every‑N‑hours and daily time modes plus jitter support
- Enhanced UI: progress bar fixes, troubleshoot panel, clearer auth flows
Full changelog
CrossWatch – v0.2.9
History release for Emby and a handful of quality-of-life tweaks...and some other things i probably forgot.
✨ Highlights
- Emby History → SIMKL/TRAKT and Plex → Emby History now works for movies and episodes.
- Resilient episode fallback.
When writing episodes, we resolve using series IDs and SxxEyy when required. Works even if per‑episode IDs are thin, as long as the series is recognizable. - Presence‑aware writes.
If Emby already shows an item as played (even without a stored date), CrossWatch avoids destructive rewrites unless you explicitly opt in.
🔧 Fixes & Changes
Emby — History
- Accurate writes: Played state is toggled through Playstate; timestamps are set via UserData only when a valid
watched_atexists. - Backdate tolerance: By default, we don’t overwrite a newer Emby date if it’s within a small window of the source time.
- Force overwrite (optional): If enabled, we unmark+remark to apply your exact timestamp (still requires a real timestamp). Disabled by default.
- Episodes: Safer resolution using SeriesId + SxxEyy; adds series year when available to assist resolution.
- Progress debug Apply logs show
wrote,forced,backdated,skip_newer,skip_played_untimed,skip_missing_date,fail_mark.
Important: When watched_at is missing, the item is skipped regardless of other flags. We never invent timestamps.
Insights – title clarity & grouping
- Smarter titles. Normalization handles minor punctuation/spacing variants and common sequel patterns.
- Series/Episode display. Episodes are labeled
Show Name S01E07(or S0 for specials), with episode names still visible in supporting columns. - Year-aware disambiguation. When two movies share a title, the year is surfaced to avoid “phantom duplicates.”
- Canonical key de‑dupe. Provider rows that only differ by harmless title quirks are collapsed under one canonical entry (counts and IDs are preserved).
- ID badges cleaned. IMDb/TMDb/TVDb are prioritized; we avoid showing the same ID twice under different casing or formats.
- Fewer false deltas. Normalized titles reduce bogus +add/−remove pairs caused by tiny title formatting differences.
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Back up `/config` before upgrade.
- Remove the complete config directory and let CrossWatch regenerate it on first start.
- Pull the latest image (`ghcr.io/cenodude/crosswatch:latest`) and verify token/library scopes in Settings after restart.
- Hourly / daily timezone‑aware scheduling with jitter
- Debug level trio (runtime.debug, runtime.debug_mods, runtime.debug_http)
- Stability knobs: snapshot_ttl_sec, apply_chunk_size, apply_chunk_pause_ms
Full changelog
CrossWatch – v0.2.8
Reliability & clarity release. Safer syncs, truer totals, and cleaner output, especially for watchlists.
✨ Highlights
- Safer one‑way sync. Handles zero‑add runs without crashing, writes are counted only when confirmed, and state/tombstones are updated accordingly.
- Truer totals (no more inflated “+adds”). Lane counters (Watchlist/Ratings/History/Playlists) now de‑duplicate per item across providers. If the same title is touched on multiple providers in one run, it’s counted once.
- Smarter delete handling. Observed‑deletes are auto‑disabled for a pair when either side doesn’t support them or is down; mass‑delete guard + optional snapshot drop‑guard keep you safe.
- Less nonsence. Blocklist + Phantom Guard suppress accidental re‑adds and record successes/failures.
- Clearer progress. Every apply phase shows attempted · added/removed · skipped · unresolved · errors; bars finish cleanly even if the final tick is missed.
- Richer final summary. “Done.” and the
run:donenow include skipped / unresolved / errors (when available).
🔧 Fixes & Changes
Orchestrator
- Always initialize add/remove result objects; read
errors/unresolvedsafely. - Final “Done.” line may include:
Total skipped,Total unresolved,Total errors. run:doneevent mirrors those totals so higher layers can surface them.
UI (Log event Beautifier)
- Final “Sync complete” card shows +added / −removed and, when present, ~skipped / !unresolved / ×errors.
📝 Note
Edge cases like “added on one provider and removed on another in the same run” are still shown as +1 and −1 (by design).
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Experimental fallback GUID for Plex when item lookup fails
Full changelog
CrossWatch – v0.2.7
Small release (from enduser perspective): but big code cleanup, a few UI touches, and a key Plex history fix.
🔧 Fixes & Changes
Plex
- History sync (SIMKL/TRAKT → Plex): Added reversed ID validation and server-wide lookup. Fixes misses from stale IDs/metadata drift; movies & shows now mark watched more reliably (still best-effort).
- Logs: Clearer skip reasons when Plex can’t resolve an item.
- Note: Syncing history/ratings from trackers (SIMKL/TRAKT) to media servers (Plex/Emby/Jellyfin) isn’t recommended. In some specific cases, this fix can help.
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Back up `/config` before upgrade.
- Remove the complete `/config` directory after stopping CrossWatch; re‑configure on start.
- Verify token scopes and library selections in Settings after pulling the latest image.
- FastAPI split into lean routers for faster, more reliable syncs
- Scheduling 2.0 with hourly/every‑N‑hours/daily_time modes, timezone support and jitter
- New debug level trio (runtime.debug, runtime.debug_mods, runtime.debug_http) and additional stability knobs
Full changelog
CrossWatch – v0.2.6
New: Emby provider (early days). Right now it supports watchlists, webhook (code is there, untested), and the Watcher.
I don’t have Emby Premiere, so webhook testing cant be done by me. History and Ratings for Emby are planned, just not shipped yet.
This is the last new provider for a while as I’m switching focus to polish and speed.
Rule of thumb:
Got Plex Pass / Emby Premiere / Jellyfin? → use webhooks.
No Pass/Premiere? → use the Watcher.
🔧 Fixes & Changes
Main
- Sync bar: a few more UI tweaks..
- Sync output: fewer “freeze-like” moments while streaming logs.
Scrobbler
- Plex ↔ Emby switch: you can toggle which one scrobbles; only one can be active. Heads-up: filters/libraries apply per provider, so review your scopes when you switch.
Emby
- Watchlist
- Supports three modes:
favorites(stars),playlist, andcollection. - Default list name comes from
watchlist_playlist_nameconfigure in UI. Dont use Playlist as it only supports movies and episodes (no shows)
- Supports three modes:
- Webhook (untested): implemented reusing Jellyfin logic; needs Emby Premiere to enable server-side webhooks.
- Watcher: polling fallback for folks without Premiere. It’s light, reliable, and works out of the box.
🧠 Known Limits (Emby)
- History / Ratings: not available yet here. Dont ask for it. It will be there when its ready.
- ID matching: works best when your Emby items have TMDB/IMDB/TVDB IDs.
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Back up `/config` before upgrade.
- If config issues appear after upgrading from v0.2.4, delete the old `config.json` and re‑configure.
- After upgrade, verify tokens and library scopes in Settings; test a single pair first then enable scheduling.
- FastAPI routers split for leaner performance and reliability
- Scheduler 2.0 with hourly/every‑N‑hours/daily_time, timezone support and jitter
- New debug levels (runtime.debug, runtime.debug_mods, runtime.debug_http) and maintenance UI actions
Full changelog
CrossWatch – v0.2.5
small but solid update: code cleanup, a few fixes, and a new experimental Plex option.
🔧 Fixes & Changes
Main
- Synchronization bar – minor UI tweaks and a tooltip so you can quickly see which phase the run is in.
- Insights accuracy – adjusted calculations so the statistics reflect more accurate totals.
Plex
- Experimental: Fallback GUID – when Plex can’t fully identify a watched or rated item (e.g., it was removed from your PMS or the lookup errors), this tries extra methods to recover IDs so the sync can proceed.
⚠️ Use only if you understand the trade-offs and are having matching issues.
Read more: https://github.com/cenodude/CrossWatch/wiki/mod_PLEX
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- If webhook behavior changes, rebuild your `config.json` by deleting it and reconfiguring.
- Review new Jellyfin settings UI after upgrade to adjust users and library whitelists.
- Webhook configuration keys were rearranged; existing `config.json` may become invalid and requires rebuild (delete and reconfigure).
- Added webhook support for Plex (`/webhook/plextrakt`) and Jellyfin (`/webhook/jellyfintrakt`).
- Introduced Authentication Providers → Jellyfin → Settings UI to change users and whitelist libraries.
- Analyzer now shows a waiting overlay for large `state.json` files.
Full changelog
CrossWatch – v0.2.4
Note: This update rearranged some webhook config keys. It should not affect your current
config.json.
If it does, rebuild your config (delete it and reconfigure).
✨ Focus - Webhook support for Plex and Jellyfin (Plex & Jellyfin → Trakt)
- Webhooks now works + Jellyfin support. Have Plex Pass? Prefer Webhook. No Plex Pass? Use the Watcher. Jellyfin users: use the Webhook.
- Endpoints:
- Plex →
/webhook/plextrakt - Jellyfin (Webhook plugin, Generic) →
/webhook/jellyfintrakt
- Plex →
- Setup guide: see the wiki for step-by-step instructions (Jellyfin users: must-read).
https://github.com/cenodude/CrossWatch/wiki/Webhooks
🔧 Fixes & Changes
Plex (History)
- Whitelist reliability: improved section ID detection for history rows so library whitelisting is consistently applied.
Jellyfin
- Improved settings: added in Authentication Providers → Jellyfin → Settings. You can now change users and whitelist libraries.
Analyzer
- Better visibility: added a waiting overlay, especially useful for larger
state.jsonfiles.
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Stop the container and back up `/config` before upgrading.
- After pulling the latest image, start CrossWatch and verify tokens and library scopes in Settings.
- Test a single sync pair first; then enable the new Scheduler if desired.
- Internal API/routers refactored; external endpoints unchanged but odd counts may appear after upgrade – use Maintenance → Clear cache.
- Scheduler 2.0 with hourly, every‑N‑hours, daily_time modes, timezone support and jitter.
- Debug level trio: runtime.debug, runtime.debug_mods, runtime.debug_http.
- Plex auth adds dedicated settings menu (server/user whitelist).
Full changelog
CrossWatch – v0.2.3
Sorry—another update. The coming weeks I’ll push more frequent fixes to squash those small annoying bugs that have been bugging me for way too long 🙂
🔧 Fixes & Changes
Main
- Sync output honors debug: Beautifier is disabled when
runtime.debugorruntime.debug_modsis true. - Live log reliability: Added SSE watchdog + auto-reconnect when the stream goes quiet; flushes the remaining buffer on error and preserves slider/stick-to-bottom.
Analyzer
- Counts match reality: Issues are filtered by enabled pairs from
/api/pairsand by enabled features (history/watchlist/ratings). - Clear footer totals: Footer now shows
Issues: N • H:x • W:y • R:zso feature backlogs can’t hide real deltas. - Pair map: Analyzer understands the new pairs schema (
source/target, per-featureenable)
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Back up `/config` before upgrading.
- Stop the container, pull the latest image (`ghcr.io/cenodude/crosswatch:latest`), then start it.
- After upgrade, verify tokens and library scopes in Settings; test a single sync pair first.
- Scheduling 2.0 with hourly, every‑N‑hours, daily time zones and jitter support
- New debug levels (`runtime.debug`, `runtime.debug_mods`, `runtime.debug_http`) and config knobs for snapshot TTL, chunk size, and pause intervals
- Enhanced UI: progress bar fixes, troubleshoot panel (clear cache, reset stats/state), clearer auth flows and in‑app wiki links
Full changelog
CrossWatch – v0.2.2
🧪 Analyzer added (early-access / best effort ... whatever)
- Helps spot items that are stuck across providers (PLEX, JELLYFIN, TRAKT, SIMKL).
- Shows Issues: N based on your sync pairs (e.g. missing peers), plus per-item suggestions and where to fix (typically Plex/Jellyfin).
- Practical UI: search, toggle IDs, resizable columns, and a footer with provider counts.
- It won’t edit SIMKL/TRAKT for you; it guides you to fix metadata at the source and then re-sync.
- If it works great—awesome. If not… at least you tried 🙂. (It’s early; feedback welcome)
- Tip: Add TMDb/Trakt keys to get smarter suggestions.
Docs: Analyzer Wiki
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Plex authentication providers now include a dedicated settings menu for server configuration, user credentials, and library whitelisting
- Jellyfin sync module enhancements allow watchlist items to be synced to Jellyfin favorites, playlists, and collections
Full changelog
CrossWatch – v0.2.1
✨ Focus
- Numbers that match reality in statistics and insight
- Multi-arch images (AMD64 + ARM64)
🔧 Fixes & Changes
- No more double counting: We stop stacking the same totals; we keep the highest number instead of adding.
- Watchlist is fair: Title tweaks/renames are shown as updated (~), not fake added (+).
- Ratings with meaning: Badges now show + / − / ~ (add, remove, update).
- Don’t miss events: Ratings/History no longer require a title, so silent providers don’t cause undercounts.
- Smarter matching: “Dune Part 2” ≈ “Dune: Part Two” (fewer bogus add+remove combos).
- Improved stability: various fixes
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Back up `/config` before upgrading.
- Stop the container, pull the latest image (`ghcr.io/cenodude/crosswatch:latest`), then start it and verify tokens and library scopes in Settings.
- Test a single sync pair first before enabling Scheduling.
- Scheduling 2.0 supports hourly, every-N-hours, daily with per-timezone start, optional jitter, manual "run now", and resilient loop.
- Two‑way sync enhancements reduce flip‑flop from weak IDs and improve source‑of‑truth handling across mixed pairs.
Full changelog
CrossWatch v0.2.0 — Big, refactored, and yes… probably many new bugs 🙂
Faster syncs, safer writes, cleaner UI. Two-way flows are steadier, SIMKL + Jellyfin behave better, Trakt refreshes itself, progress bar is sane, scheduler is actually useful. Breakage risk is low but back up /config anyway.
Highlights
- Big refactor: FastAPI split into lean routers; providers + orchestrator modules cleaned up for speed and reliability.
- Safer syncs: Mass-delete guard rails, health status and “suspect shrink” protection; additions/updates chunked; smarter delta reuse.
- Two-way sync that sticks: Less flip-flop from weak IDs; better source-of-truth handling across mixed pairs.
- Scheduling 2.0: Hourly / every-N-hours / daily time, per-timezone, optional jitter, manual “run now”, resilient loop.
- Debug levels:
Off·On·On + MOD debug·On (full HTTP)best isOn + MOD debug - Auth mod Plex improvement: in authentication providers there is now a new settings menu for Plex (server settings, user settings and whitelisting of libraries)
- Sync mod Jellyfin improvement: many fixes, should work better now. Also watchlist can now sync to favorites, Playlist and Collections
- Watchlist: new GUID normalizations will provide better results
What’s new (user-visible)
UI/UX
- Progress bar partly fixed: No early jump to 90%. “Apply” phase is shown only after all snapshots complete.
- Run safety: Start/stop visuals are guarded (no more
startRunVisuals is not defined). - Troubleshoot panel: One-click Clear cache, Reset stats, Reset state.
- Auth flows: Plex PIN and SIMKL OAuth are smoother; clearer status + error toasts.
- Wiki surfaced: Help links right in the app (Getting Started, Config, FAQ).
Providers
- Plex
- Server URL is sticky: Suggestions won’t override a value already saved in config.
- Better library scoping and discovery hints.
- SIMKL
- Fresh “present” snapshots when activity changes (bypasses stale ETag/304). Fewer “why didn’t my add propagate?” moments.
- Trakt
- Auto token refresh before/after calls; 401/403 retries wired in.
- Jellyfin
- Capability reporting cleaned up; fewer re-add loops via smarter ID/shadow handling.
Orchestrator
- Faster snapshots; smarter enrichment ordering; fewer duplicate passes.
- Safer writes with chunking + tiny pauses to avoid API spikes.
- Telemetry (opt-in) trimmed and less noisy.
Scheduling
- Modes:
disabled | hourly | every_n_hours | daily_time. - Timezone-aware start; optional
jitter_secondsto avoid herd starts. - Visible “next run at” + last result in the UI.
Config (still JSON, still simple)
- New debug trio:
runtime.debug,runtime.debug_mods,runtime.debug_http. - Stability knobs:
snapshot_ttl_sec,apply_chunk_size,apply_chunk_pause_ms,
and mass-shrink guards (suspect_min_prev,suspect_shrink_ratio).
Fixed (the greatest hits)
- Watchlist delete (SIMKL/Trakt): actually removes items and stays removed.
- Endless re-adds from weak/agent IDs reduced (IMDb/TMDb/TVDb priority).
- Insight/List noise reduced (hide disconnected providers).
- UI errors from timing/race conditions hardened.
Breaking/behavior changes
- Internal API/routers were refactored; external endpoints remain the same for normal use.
- If you see odd counts after upgrade: use Maintenance → Clear cache and hard-refresh the UI.
Upgrade notes
- Stop container; back up your
/config. - Remove your complete /config
- Pull latest:
ghcr.io/cenodude/crosswatch:latest. - Start; visit Settings → verify tokens + library scopes.
- Test one pair first; then enable Scheduling if desired.
Known rough edges (being honest)
- Stats can be off in edge cases (work in progress).
- Some UI sections don’t auto-refresh perfectly (do manual refresh).
- SIMKL & Jellyfin are still maturing; report weirdness with logs.
- see WIKI for more issues: https://github.com/cenodude/CrossWatch/wiki
- Removed auto-refresh feature; manual refresh only
Full changelog
CrossWatch – v0.1.7
✨ Focus | Road to redemption -> v0.2.0
- API split: FastAPI monolith refactored into lean routers. Same endpoints, cleaner internals. Foundation for 0.2.0.
🔧 Fixes & Changes
- Watchlist delete: fixed the broken delete flow; it works now. More hardening to follow.
CrossWatch – v0.1.6
✨ Focus
- Road to redemption to v0.2.0: deep cleanup and refactors to future-proof the codebase. Fewer features for now, more fixes and polish.
🔧 Fixes & Changes
- Watchlist normalization: IMDb-first ID priority to cut false positives during sync.
- Auto-refresh removed: it caused more trouble than it solved. Manual refresh only (for now).
🐞 Waiting to be fixed
- Statistics: Counts can be incorrect in certain scenarios (filters, caching, mixed sources).
- Main Insight: Counts can be incorrect in certain scenarios (filters, caching, mixed sources).
CrossWatch – v0.1.5
This build changes caching + type handling. Clear your local state: delete /config/.cw_state/ and /config/state.json — or hit the three red buttons in Settings → Troubleshoot.
🔧 Fixes & Improvements
- History sync: Plex play dates weren’t fetched reliably, causing Trakt to log everything on the same day.
- History sync: Some plays showed as “successful” but weren’t written to Trakt.
- Endless re-adds: items without usable IDs (esp. Plex
none://GUIDs) kept trying every run. - Enrichment: failed with
unexpected keyword argument 'items'. - Provider flags: mismatch in
provides_idscaused skipped enrichments. - Jellyfin: didn’t expose capabilities cleanly.
- List view clutter: Genre overflow, large gaps, Poster column wasted space.
- Sync/Insight noise: showed providers the user hadn’t connected.
- Type rename fallout: switching show → tv mislabelled some titles.
- Pairs enablement: Enabled/disabled flags weren’t honored; the orchestrator ran pairs regardless.
- Metadata enrichment
- Unified call signature (
resolve/resolve_many); no moreitemserror. - Plex GUIDs decoded into TMDB/IMDb/TVDB IDs automatically.
- Unified call signature (
- Provider consistency
- All providers declare
"provides_ids": falseso enrichment always runs. - SIMKL ratings support exposed (movies/shows/episodes).
- Jellyfin now reports
capabilities()explicitly.
- All providers declare
- Two-way sync
- Removed duplicate enrichment passes; each side enriches once.
- Watchlist stability
- Type normalization:
tv/show/series/season/episode⇒ tv. - Choose richest-ID source (tmdb/imdb/tvdb/trakt/slug) as the base; weak rows can’t override.
- Stops bogus add/remove loops from type flips.
- Type normalization:
- UI: List view
- Genre clamped to 2 lines (tooltip shows full text).
- Columns tightened (Release/Genre/Type/Sync) to sit closer to Title.
- Poster column compact and aligned; no wasted right-side gap.
- Only show what matters
- Sync column shows connected providers only.
- List Insight tiles also hide disconnected providers.
🐞 Waiting to be fixed
- Watchlist thrash: Items flip between movie and tv, causing add/remove loops.
- Statistics: Counts can be incorrect in certain scenarios (filters, caching, mixed sources).
- Main Insight: Counts can be incorrect in certain scenarios (filters, caching, mixed sources).
- Removed auto-refresh feature; only manual refresh is now supported.
Full changelog
CrossWatch – v0.1.6
✨ Focus
- Road to redemption to v0.2.0: deep cleanup and refactors to future-proof the codebase. Fewer features for now, more fixes and polish.
🔧 Fixes & Changes
- Watchlist normalization: IMDb-first ID priority to cut false positives during sync.
- Auto-refresh removed: it caused more trouble than it solved. Manual refresh only (for now).
CrossWatch – v0.1.5
This build changes caching + type handling. Clear your local state: delete /config/.cw_state/ and /config/state.json — or hit the three red buttons in Settings → Troubleshoot.
🔧 Fixes & Improvements
- History sync: Plex play dates weren’t fetched reliably, causing Trakt to log everything on the same day.
- History sync: Some plays showed as “successful” but weren’t written to Trakt.
- Endless re-adds: items without usable IDs (esp. Plex
none://GUIDs) kept trying every run. - Enrichment: failed with
unexpected keyword argument 'items'. - Provider flags: mismatch in
provides_idscaused skipped enrichments. - Jellyfin: didn’t expose capabilities cleanly.
- List view clutter: Genre overflow, large gaps, Poster column wasted space.
- Sync/Insight noise: showed providers the user hadn’t connected.
- Type rename fallout: switching show → tv mislabelled some titles.
- Pairs enablement: Enabled/disabled flags weren’t honored; the orchestrator ran pairs regardless.
- Metadata enrichment
- Unified call signature (
resolve/resolve_many); no moreitemserror. - Plex GUIDs decoded into TMDB/IMDb/TVDB IDs automatically.
- Unified call signature (
- Provider consistency
- All providers declare
"provides_ids": falseso enrichment always runs. - SIMKL ratings support exposed (movies/shows/episodes).
- Jellyfin now reports
capabilities()explicitly.
- All providers declare
- Two-way sync
- Removed duplicate enrichment passes; each side enriches once.
- Watchlist stability
- Type normalization:
tv/show/series/season/episode⇒ tv. - Choose richest-ID source (tmdb/imdb/tvdb/trakt/slug) as the base; weak rows can’t override.
- Stops bogus add/remove loops from type flips.
- Type normalization:
- UI: List view
- Genre clamped to 2 lines (tooltip shows full text).
- Columns tightened (Release/Genre/Type/Sync) to sit closer to Title.
- Poster column compact and aligned; no wasted right-side gap.
- Only show what matters
- Sync column shows connected providers only.
- List Insight tiles also hide disconnected providers.
🐞 Waiting to be fixed
- Watchlist thrash: Items flip between movie and tv, causing add/remove loops.
- Statistics: Counts can be incorrect in certain scenarios (filters, caching, mixed sources).
- Main Insight: Counts can be incorrect in certain scenarios (filters, caching, mixed sources).
⚠
- Clearing local state required: delete `/config/.cw_state/` and `/config/state.json` before use.
Full changelog
CrossWatch – v0.1.5
This build changes caching + type handling. Clear your local state: delete /config/.cw_state/ and /config/state.json — or hit the three red buttons in Settings → Troubleshoot.
🔧 Fixes & Improvements
- History sync: Plex play dates weren’t fetched reliably, causing Trakt to log everything on the same day.
- History sync: Some plays showed as “successful” but weren’t written to Trakt.
- Endless re-adds: items without usable IDs (esp. Plex
none://GUIDs) kept trying every run. - Enrichment: failed with
unexpected keyword argument 'items'. - Provider flags: mismatch in
provides_idscaused skipped enrichments. - Jellyfin: didn’t expose capabilities cleanly.
- List view clutter: Genre overflow, large gaps, Poster column wasted space.
- Sync/Insight noise: showed providers the user hadn’t connected.
- Type rename fallout: switching show → tv mislabelled some titles.
- Pairs enablement: Enabled/disabled flags weren’t honored; the orchestrator ran pairs regardless.
- Metadata enrichment
- Unified call signature (
resolve/resolve_many); no moreitemserror. - Plex GUIDs decoded into TMDB/IMDB/TVDB IDs automatically.
- Unified call signature (
- Provider consistency
- All providers declare
"provides_ids": falseso enrichment always runs. - SIMKL ratings support exposed (movies/shows/episodes).
- Jellyfin now reports
capabilities()explicitly.
- All providers declare
- Two-way sync
- Removed duplicate enrichment passes; each side enriches once.
- Watchlist stability
- Type normalization:
tv/show/series/season/episode⇒ tv. - Choose richest-ID source (tmdb/imdb/tvdb/trakt/slug) as the base; weak rows can’t override.
- Stops bogus add/remove loops from type flips.
- Type normalization:
- UI: List view
- Genre clamped to 2 lines (tooltip shows full text).
- Columns tightened (Release/Genre/Type/Sync) to sit closer to Title.
- Poster column compact and aligned; no wasted right-side gap.
- Only show what matters
- Sync column shows connected providers only
- List Insight tiles also hide disconnected providers.
🐞 Waiting to be fixed....
- Watchlist thrash: Items flipped between movie and tv, causing add/remove loops.
- Statistics Counts can be incorrect in certain scenarios (filters, caching, mixed sources).
- Main Insight Counts can be incorrect in certain scenarios (filters, caching, mixed sources).
⚠️ Status & Safety
- This project is in very early development and not ready for production.
- Always make backups/exports of your history before running a real sync.
- Prefer dry runs first to inspect plans (especially timestamps).
- Exponential backoff and TTL purge for unresolved items
- Rolling shadows for ratings and history to stabilize snapshots
Full changelog
Version v0.1.4
🐞 Short summary of issues users hit
- History timestamps: first sync didn’t carry original
watched_at→ Trakt saw plays as “today”, creating same-day duplicates. - Jellyfin fields: not always requesting
UserDatacaused us to missLastPlayedDate. - Watcher: some improvements when re-watching the same movie/show/episode
- Watchlist noise: unresolved items (esp. episodes) could keep suppressing diffs indefinitely.
🔧 Fixes & Improvements
-
History / Timestamps
- Always read and propagate source play time:
- Plex:
viewedAt - Jellyfin:
UserData.LastPlayedDate(fallbackDateLastPlayed)
- Plex:
- Normalize to UTC; no more silent “now” backfills when a timestamp is missing (we flag instead).
- History query (Jellyfin) uses
Fields=UserData,ProductionYear+EnableUserData=trueand sorts byDatePlayed.
-We’ve temporarily disabled the History feature for SIMKL because it isn’t working correctly.
- Always read and propagate source play time:
-
Jellyfin connector
- All features enabled (except playlists) - Watchlists, Ratings, History
- Watchlist:
- “Favorites” (Movies/Series) or named Playlist. as Jellyfin doesnt have any Watchlist
- Ignore items without cross IDs to avoid churn.
-
Unresolved/backoff system
- Track failures with exponential backoff (default base 6h, cap 30d) or virtual policy.
- TTL purge (default 90d) + stats by reason/type.
- Auto-reset a slice on large library growth to retry fresh matches.
-
State & Shadows
- Rolling ratings and history shadows to stabilize snapshots and quick re-runs.
- Cursor fingerprints guard against noisy reindexes.
-
Apply paths
- Favorites add/remove uses dedicated endpoints; verified via
UserData.IsFavorite, falls back to/Items/{id}/UserDatawhen needed. - Ratings write/unrate coerces to Trakt-style 10-scale (with 5-star inputs doubled).
- Favorites add/remove uses dedicated endpoints; verified via
-
DX & Ops
- Lightweight HTTP stats (status, bytes, latency).
- Runtime
debugtoggles structured debug logs. - Manifest + config schema updated (watchlist modes, unresolved policy).
⚠️ Status & Safety
- This project is in very early development and not ready for production.
- Always make backups/exports of your history before running a real sync.
- Prefer dry runs first to inspect plans (especially timestamps).
- Safe first run suppresses removals to prevent accidental wipes.
- History sync enabled.
- Experimental Jellyfin support added (limited functionality).
Full changelog
Version v0.1.3
🔧 Critical Fixes
-
Scrobble / Watcher — make “watched” earned, not guessed
STOPbelow threshold ⇒ sent asPAUSE(default 80%,scrobble.trakt.stop_pause_threshold).- Anti “100% STOP jump”: demote to
PAUSEand clamp progress to last known. - Credits-safe: final
STOP≥95% bypasses debounce (scrobble.trakt.force_stop_at). - Probe-correct progress from Plex (≤3 tries); floor tiny
startto 1%. - Suppress dup
STOP; lightweight restart detection; stable reconnect/backoff.
-
Trakt Sink — smarter IDs, safer sends
- Prefer episode GUID IDs (
imdb/tmdb/tvdb/trakt) → fallback show+S/E → last-resort GUID search (fixes anime reorders like S02E04→S01E16). - Handles 401 refresh, 429 backoff; cleaner logs and payloads.
- Prefer episode GUID IDs (
Version v0.1.2
🔄 Sync & Pairing
- Safe first run — removals are suppressed to prevent accidental wipes.
- History sync — enabled.
- Jellyfin added — experimental support (limited functionality; known issues).
🧩 Watchlist UX
- Dynamic insights (4+ providers) — layout scales cleanly to any number of providers; metrics update live.
- Trailer playback — fixed the watchlist trailer launch/preview issue.
🔧 Critical Fixes
- Sync button state — the Synchronize button enables correctly even when no SIMKL provider is in a pair.
- Many other fixes and hardenings.
🐳 Run CrossWatch with Docker
Latest stable
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
- History sync enabled
- Experimental Jellyfin support (limited functionality)
- Dynamic insights layout scales to any number of providers with live metric updates
Full changelog
Version v0.1.2
🔄 Sync & Pairing
- Safe first run — removals are suppressed to prevent accidental wipes.
- History sync — enabled.
- Jellyfin added — experimental support (limited functionality; known issues).
🧩 Watchlist UX
- Dynamic insights (4+ providers) — layout scales cleanly to any number of providers; metrics update live.
- Trailer playback — fixed the watchlist trailer launch/preview issue.
🔧 Critical Fixes
- Sync button state — the Synchronize button enables correctly even when no SIMKL provider is in a pair.
- Many other fixes and hardenings.
🐳 Run CrossWatch with Docker
Latest stable
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
- Ratings feature enabled
- VIP users receive additional Plex and Trakt connection information
Full changelog
Version v0.1.1
What’s new
- Ratings (is now enabled)
- Connections will now provide additional information if you're VIP user for Plex and Trakt
- UI changes many..many..many small adjustments .....
🐳 Run CrossWatch with Docker
Latest stable
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
Previous versions
🔧 Critical Fixes
- Watcher autostart after reboot — Startup hook always bound; watcher auto-starts when Scrobble → Mode: Watch
- SIMKL Sync Mod now supports Anime
- Watchlist deletes that “came back” — True server fan-out (PLEX/SIMKL/TRAKT), correct ID resolution, immediate state prune
- Trakt “Now Playing” — Start events clamped (≥1%), Plex progress aligned,
ratingKeycarried → reliable now playing for movies & shows. - SIMKL freshness (no spam) — Present PTW snapshot force-refreshes only when activities move; otherwise cached → fast propagation with minimal calls.
- Faster posters — First screen eager, rest lazy; cache-control enables instant re-show + silent revalidate.
🧩 UX Polish
- Delete feedback — Spinner + progress bar during multi-deletes so you can see it working.
✅ Reduced SIMKL & TRAKT API calls
- Smarter snapshot caching — Refresh only when activity timestamps change.
- Cursor-aware deltas — Fetch just new/changed items, not whole lists.
🧩 Watchlist UX
- Instant delete refresh — Posters vanish immediately on delete.
- Accurate snackbar — Shows the real number of items removed.
🔧 Critical Fixes
- Watcher autostart — Startup hook always bound; watcher auto-starts when Scrobble → Watch + Autostart are on.
- Pairs preserved on Save — Saving Settings no longer wipes Pairs; manage them only via Synchronization → Pairs.
🔄 Sync & Pairing
- Smarter two-way syncs — Reliable across mixed pairs (e.g., SIMKL ↔ TRAKT, PLEX ↔ SIMKL).
- Delete once → gone everywhere — Deletions cascade across services within the same run.
- Safe first run — Removals suppressed to avoid accidental wipes.
- Fewer mismatches — Better ID/alias matching across services.
- Stable SIMKL snapshots — Shadow + cursor keep deltas predictable.
📺 Watcher / Scrobble
- Progress accuracy — No more bogus 100% spikes.
- Seek handling — Scrubbing updates correctly.
- Restart detection — Proper reset at 0%.
- Cleaner logs — Reduced Plex progress/activity noise.
- Bi-directional sync across multiple service pairs (e.g., Plex ↔ SIMKL, Trakt ↔ Plex)
- Live Trakt scrobbling without requiring webhooks
- Advanced scheduling with if/else logic
Full changelog
🎉 Milestone Reached: v0.1.0
We’ve hit version 0.1.0 — a big step forward. The core modules are stable, and the Watchlist is now fully functional and polished. That means we’re ready to start lighting up the currently disabled features and growing the experience.
What’s solid in 0.1.0
- Reliable core foundation (auth,metadata and sync modules) and data flow
- Bi-directional sync across multiple pairs (e.g., Plex ↔ SIMKL, Trakt ↔ Plex).
- Live Trakt scrobbling — no webhooks required.
- Advanced Scheduling - If/else statements
What’s next (in early 0.x roadmap)
- Ratings (first-class, with cross-service sync)
- Watchlist automation Automatically removes titles from your (Plex) Watchlist once you’ve watched them
- Performance & reliability (telemetry, error recovery)...basically ongoing business
Thanks for sticking with me at this stage. v0.1.0 gets the essentials right. Now we can move faster on the exciting bits like ratings and discovery. Onward!
- A fast, refined Watchlist:
- Posters & List views with saved preferences
- Compact detail bar with score, trailer, and provider badges
- Powerful filters (including Released/Genre) and a “More…” panel
- Sortable List headers and tidy layout
What’s next (in early 0.x roadmap)
- Ratings (first-class, with cross-service sync)
- Watchlist automation Automatically removes titles from your (Plex) Watchlist once you’ve watched them
- Performance & reliability (telemetry, error recovery)...basically ongoing business
Thanks for sticking with us at this stage. v0.1.0 gets the essentials right—now we can move faster on the exciting bits like ratings and discovery. Onward!
🐳 Run CrossWatch with Docker
Latest stable
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
Previous versions
🔧 Critical Fixes
- Watcher autostart after reboot — Startup hook always bound; watcher auto-starts when Scrobble → Mode: Watch
- SIMKL Sync Mod now supports Anime
- Watchlist deletes that “came back” — True server fan-out (PLEX/SIMKL/TRAKT), correct ID resolution, immediate state prune
- Trakt “Now Playing” — Start events clamped (≥1%), Plex progress aligned,
ratingKeycarried → reliable now playing for movies & shows. - SIMKL freshness (no spam) — Present PTW snapshot force-refreshes only when activities move; otherwise cached → fast propagation with minimal calls.
- Faster posters — First screen eager, rest lazy; cache-control enables instant re-show + silent revalidate.
🧩 UX Polish
- Delete feedback — Spinner + progress bar during multi-deletes so you can see it working.
✅ Reduced SIMKL & TRAKT API calls
- Smarter snapshot caching — Refresh only when activity timestamps change.
- Cursor-aware deltas — Fetch just new/changed items, not whole lists.
🧩 Watchlist UX
- Instant delete refresh — Posters vanish immediately on delete.
- Accurate snackbar — Shows the real number of items removed.
🔧 Critical Fixes
- Watcher autostart — Startup hook always bound; watcher auto-starts when Scrobble → Watch + Autostart are on.
- Pairs preserved on Save — Saving Settings no longer wipes Pairs; manage them only via Synchronization → Pairs.
🔄 Sync & Pairing
- Smarter two-way syncs — Reliable across mixed pairs (e.g., SIMKL ↔ TRAKT, PLEX ↔ SIMKL).
- Delete once → gone everywhere — Deletions cascade across services within the same run.
- Safe first run — Removals suppressed to avoid accidental wipes.
- Fewer mismatches — Better ID/alias matching across services.
- Stable SIMKL snapshots — Shadow + cursor keep deltas predictable.
📺 Watcher / Scrobble
- Progress accuracy — No more bogus 100% spikes.
- Seek handling — Scrubbing updates correctly.
- Restart detection — Proper reset at 0%.
- Cleaner logs — Reduced Plex progress/activity noise.
- Instant delete refresh removes posters immediately on watchlist deletion
- Accurate snackbar displays the exact number of items removed
Full changelog
What’s new in v0.0.9
🔧 Critical Fixes
- Watcher autostart after reboot — Startup hook always bound; watcher auto-starts when Scrobble → Mode: Watch
- SIMKL Sync Mod now supports Anime
- Watchlist deletes that “came back” — True server fan-out (PLEX/SIMKL/TRAKT), correct ID resolution, immediate state prune
- Trakt “Now Playing” — Start events clamped (≥1%), Plex progress aligned,
ratingKeycarried → reliable now playing for movies & shows. - SIMKL freshness (no spam) — Present PTW snapshot force-refreshes only when activities move; otherwise cached → fast propagation with minimal calls.
- Faster posters — First screen eager, rest lazy; cache-control enables instant re-show + silent revalidate.
🧩 UX Polish
- Delete feedback — Spinner + progress bar during multi-deletes so you can see it working.
🐳 Run CrossWatch with Docker
Latest stable
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
Previous versions
✅ Reduced SIMKL & TRAKT API calls
- Smarter snapshot caching — Refresh only when activity timestamps change.
- Cursor-aware deltas — Fetch just new/changed items, not whole lists.
🧩 Watchlist UX
- Instant delete refresh — Posters vanish immediately on delete.
- Accurate snackbar — Shows the real number of items removed.
🔧 Critical Fixes
- Watcher autostart — Startup hook always bound; watcher auto-starts when Scrobble → Watch + Autostart are on.
- Pairs preserved on Save — Saving Settings no longer wipes Pairs; manage them only via Synchronization → Pairs.
🔄 Sync & Pairing
- Smarter two-way syncs — Reliable across mixed pairs (e.g., SIMKL ↔ TRAKT, PLEX ↔ SIMKL).
- Delete once → gone everywhere — Deletions cascade across services within the same run.
- Safe first run — Removals suppressed to avoid accidental wipes.
- Fewer mismatches — Better ID/alias matching across services.
- Stable SIMKL snapshots — Shadow + cursor keep deltas predictable.
📺 Watcher / Scrobble
- Progress accuracy — No more bogus 100% spikes.
- Seek handling — Scrubbing updates correctly.
- Restart detection — Proper reset at 0%.
- Cleaner logs — Reduced Plex progress/activity noise.
- Requires resetting state (via Settings → Troubleshoot) before first synchronization when upgrading from any version <0.0.5.
Full changelog
What’s new in v0.0.8
✅ Greatly reduced SIMKL and TRAKT API calls
- Smarter snapshot caching
Watchlist snapshots are now locally cached and only refreshed when SIMKL or TRAKT activity timestamps change. - Cursor-aware delta sync
Instead of reloading entire watchlists every run, only new or changed items are requested.
🧩 Watchlist UX
- Instant UI refresh on delete
Posters disappear immediately from the watchlist as soon as you delete them — no more waiting for a backend refresh. - Accurate snackbar messages
The snackbar now shows the actual number of deleted items instead of just reflecting network status.
Previous versions
Critical Fixes
-
Watcher autostart after reboot
Some installs didn’t start the Plex watcher on boot because the app’s startup hook wasn’t attached.
✅ Fixed: the startup hook is now always bound → watcher starts automatically whenScrobble → Mode: Watch+Autostartis on. -
Pairs not showing after saving settings
In a few flows, clicking Save in Settings could overwrite the config without the current pairs.
✅ Fixed: config saves no longer wipe pairs; the Pairs list is preserved and managed only via the Synchronization → Pairs screen.
🔄 Sync & Pairing Improvements
- Smarter two-way syncs across multiple pairs — Works great with setups like SIMKL ↔ TRAKT alongside PLEX ↔ SIMKL (any combination/ordering).
- “Delete once → gone everywhere” — If you remove an item on one service, CrossWatch now cascades that deletion to all other services within the same sync run (no more lingering items until the next run).
- No accidental first-run wipes — On the very first sync, removals are automatically suppressed to avoid mass deletions while CrossWatch learns your libraries.
- Fewer mismatches — ID/linking and alias matching are improved so items are recognized as the same movie/show across services.
- Better snapshots for SIMKL — Uses a local shadow/cursor for SIMKL watchlists to keep deltas accurate and predictable.
📺 Watcher / Scrobble Fixes
- Progress Accuracy — Fixed incorrect
100%spikes sent to Trakt when pausing or stopping playback. - Seek Handling — Corrected behavior when scrubbing backward; progress now updates properly instead of jumping or freezing.
- Restart Detection — Properly resets progress when playback restarts at
0%after previously being mid-way. - Noise Reduction — Removed spammy Plex
progress/activityalerts from logs for cleaner output.
🧰 IMPORTANT
- Reset state / rebuild snapshot: if you are upgrading from a previous version <0.0.5 reset state (settings - troubleshoot) before you synchronize the first-run
🐳 Run CrossWatch with Docker
Latest stable
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
- If upgrading from a version <0.0.5, reset state (Settings → Troubleshoot) before the first synchronization.
- Smarter two‑way sync across multiple pairs
- Cascading deletions to all services in the same sync run
- Suppressed first‑run removals and improved ID/linking matching
Full changelog
🚀 What’s new in v0.0.7
🧯 Critical Fixes
-
Watcher autostart after reboot
Some installs didn’t start the Plex watcher on boot because the app’s startup hook wasn’t attached.
✅ Fixed: the startup hook is now always bound → watcher starts automatically whenScrobble → Mode: Watch+Autostartis on. -
Pairs not showing after saving settings
In a few flows, clicking Save in Settings could overwrite the config without the current pairs.
✅ Fixed: config saves no longer wipe pairs; the Pairs list is preserved and managed only via the Synchronization → Pairs screen.
🔄 Sync & Pairing Improvements
- Smarter two-way syncs across multiple pairs — Works great with setups like SIMKL ↔ TRAKT alongside PLEX ↔ SIMKL (any combination/ordering).
- “Delete once → gone everywhere” — If you remove an item on one service, CrossWatch now cascades that deletion to all other services within the same sync run (no more lingering items until the next run).
- No accidental first-run wipes — On the very first sync, removals are automatically suppressed to avoid mass deletions while CrossWatch learns your libraries.
- Fewer mismatches — ID/linking and alias matching are improved so items are recognized as the same movie/show across services.
- Better snapshots for SIMKL — Uses a local shadow/cursor for SIMKL watchlists to keep deltas accurate and predictable.
📺 Watcher / Scrobble Fixes
- Progress Accuracy — Fixed incorrect
100%spikes sent to Trakt when pausing or stopping playback. - Seek Handling — Corrected behavior when scrubbing backward; progress now updates properly instead of jumping or freezing.
- Restart Detection — Properly resets progress when playback restarts at
0%after previously being mid-way. - Noise Reduction — Removed spammy Plex
progress/activityalerts from logs for cleaner output.
🧰 IMPORTANT
- Reset state / rebuild snapshot: if you are upgrading from a previous version <0.0.5 reset state (settings - troubleshoot) before you synchronize the first-run
🐳 Run CrossWatch with Docker
Latest stable
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
- For upgrades from versions <0.0.5, reset state (Settings → Troubleshoot) before first synchronization
- Smarter two‑way sync across multiple pairs (e.g., SIMKL↔TRAKT, PLEX↔SIMKL)
- Cascading deletion: removing an item on one service deletes it everywhere in the same sync run
- Improved ID/linking and alias matching to reduce mismatches between services
Full changelog
🛠 Recent Fixes v0.0.6
Small but important release. Two annoying bugs squashed: watcher autostart and pairs disappearing after Save.
🚀 What’s new in v0.0.6
🧯 Critical Fixes
-
Watcher autostart after reboot
Some installs didn’t start the Plex watcher on boot because the app’s startup hook wasn’t attached.
✅ Fixed: the startup hook is now always bound → watcher starts automatically whenScrobble → Mode: Watch+Autostartis on. -
Pairs not showing after saving settings
In a few flows, clicking Save in Settings could overwrite the config without the current pairs.
✅ Fixed: config saves no longer wipe pairs; the Pairs list is preserved and managed only via the Synchronization → Pairs screen.
🔄 Sync & Pairing Improvements
- Smarter two-way syncs across multiple pairs — Works great with setups like SIMKL ↔ TRAKT alongside PLEX ↔ SIMKL (any combination/ordering).
- “Delete once → gone everywhere” — If you remove an item on one service, CrossWatch now cascades that deletion to all other services within the same sync run (no more lingering items until the next run).
- No accidental first-run wipes — On the very first sync, removals are automatically suppressed to avoid mass deletions while CrossWatch learns your libraries.
- Fewer mismatches — ID/linking and alias matching are improved so items are recognized as the same movie/show across services.
- Better snapshots for SIMKL — Uses a local shadow/cursor for SIMKL watchlists to keep deltas accurate and predictable.
📺 Watcher / Scrobble Fixes
- Progress Accuracy — Fixed incorrect
100%spikes sent to Trakt when pausing or stopping playback. - Seek Handling — Corrected behavior when scrubbing backward; progress now updates properly instead of jumping or freezing.
- Restart Detection — Properly resets progress when playback restarts at
0%after previously being mid-way. - Noise Reduction — Removed spammy Plex
progress/activityalerts from logs for cleaner output.
🧰 IMPORTANT
- Reset state / rebuild snapshot: if you are upgrading from a previous version <0.0.5 reset state (settings - troubleshoot) before you synchronize the first-run
🐳 Run CrossWatch with Docker
Latest stable
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
- When upgrading from a version <0.0.5, reset state (Settings → Troubleshoot) before performing the first synchronization.
- Smarter two‑way sync across multiple service pairs (e.g., SIMKL↔TRAKT, PLEX↔SIMKL)
- Cascading deletions: removal on one service propagates to all others within the same sync run
- Improved ID/alias matching reduces mismatches between services
Full changelog
🛠 Recent Fixes v0.0.5
🔄 Sync & Pairing Improvements
- Smarter two-way syncs across multiple pairs — Works great with setups like SIMKL ↔ TRAKT alongside PLEX ↔ SIMKL (any combination/ordering).
- “Delete once → gone everywhere” — If you remove an item on one service, CrossWatch now cascades that deletion to all other services within the same sync run (no more lingering items until the next run).
- No accidental first-run wipes — On the very first sync, removals are automatically suppressed to avoid mass deletions while CrossWatch learns your libraries.
- Fewer mismatches — ID/linking and alias matching are improved so items are recognized as the same movie/show across services.
- Better snapshots for SIMKL — Uses a local shadow/cursor for SIMKL watchlists to keep deltas accurate and predictable.
📺 Watcher / Scrobble Fixes
- Progress Accuracy — Fixed incorrect
100%spikes sent to Trakt when pausing or stopping playback. - Seek Handling — Corrected behavior when scrubbing backward; progress now updates properly instead of jumping or freezing.
- Restart Detection — Properly resets progress when playback restarts at
0%after previously being mid-way. - Noise Reduction — Removed spammy Plex
progress/activityalerts from logs for cleaner output.
🧰 IMPORTANT
- Reset state / rebuild snapshot: if you are upgrading from a previous version <0.0.5 reset state (settings - troubleshoot) before you synchronize the first-run
🐳 Run CrossWatch with Docker
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
Fixed incorrect 100% progress spikes, seek handling, and restart detection in playback tracking.
Full changelog
🛠 Recent Fixes v0.0.4
📺 Watcher / Scrobble Fixes
- Progress Accuracy — Fixed incorrect
100%spikes sent to Trakt when pausing or stopping playback. - Seek Handling — Corrected behavior when scrubbing backward; progress now updates properly instead of jumping or freezing.
- Restart Detection — Properly resets progress when playback restarts at
0%after previously being mid-way. - Noise Reduction — Removed spammy Plex
progress/activityalerts from logs for cleaner output.
🐳 Run CrossWatch with Docker
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
- Added settings overview
- Improvements in Watchlist
Full changelog
v0.0.3
Minor bug fixes:
- Optimized scheduler and sync times
- Added settings overview
- Improvements in Watchlist
v0.0.2
Minor bug fixes:
- Optimized scrobbler watcher
- Fixed non-working PIN copy buttons
🐳 Run CrossWatch with Docker
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
Fixed non-working PIN copy buttons.
Full changelog
v0.0.2
Minor bug fixes:
- Optimized scrobbler watcher
- Fixed non-working PIN copy buttons
🐳 Run CrossWatch with Docker
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest
Initial release with sync features disabled by design.
Full changelog
Initial Release
Note: Ratings, watch history, and playlists sync are currently disabled by design.
The code for these features is already included, but they are not yet fully tested and will be enabled in a future release.
🐳 Run CrossWatch with Docker
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v /path/to/config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest