Skip to content

Rebase the fork onto upstream 2.12.2 - #14

Merged
WouterStulp merged 57 commits into
mainfrom
sync/upstream-2.12.2
Oct 8, 2026
Merged

WouterStulp merged 57 commits into
mainfrom
sync/upstream-2.12.2

Conversation

@WouterStulp

Copy link
Copy Markdown
Owner

Rebuilds the fork on top of upstream v2.12.2, then re-applies the fork's own changes. Releases as 2.12.2.1.

Upstream merged most of the fork's work itself (builtbyproxy#142, builtbyproxy#144, builtbyproxy#146, builtbyproxy#148, builtbyproxy#149, builtbyproxy#153, builtbyproxy#157 contain the fork's commits under its author; builtbyproxy#145 and builtbyproxy#159 reimplemented fork ideas), so a plain merge produced ~110 conflicts between two versions of the same code. Instead this branch starts from upstream/main and cherry-picks only what upstream doesn't have. A final -s ours merge links the old fork history so the protected main takes it as a normal PR, no force-push.

Re-applied fork changes (cherry-picked with -x, original author kept)

  • Serializd: currently watching, finished shows marked watched (ended shows only), finished-show cache
  • ntfy notifications: sync needs attention, Serializd login rejected, Letterboxd login breaker; the ntfy token is now write-only like the other secrets, and the test endpoint is admin-only with a fixed error
  • No telemetry, no "send logs to developer", no workers.dev mirror; also removes upstream's newer telemetry previews and opt-in banner (feat: see exactly what telemetry and log bundles send builtbyproxy/Jellyscribe#154)
  • dd-mm-yy dates (now in the shared jellyscribe.js)
  • No author credit under the logo; fork README with a privacy note (now also mentioning the optional ntfy topic)
  • Account switches grouped (Sync / Watchlist & Seerr / Advanced); upstream's own confirm-before-remove is used
  • Scrollable status chips on phones
  • Trimmed upstream-only files (openspec, site, worker, live/version/docs workflows); fork release pipeline (release.yml on published release, manifest as release asset)

Dropped in favour of upstream

One behaviour-related test change: the fork's "film abandoned → ntfy" test now throws FilmNotFoundException, because upstream only gives up on a film after 3 permanent failures; a generic error no longer abandons. Assertions unchanged.

Verified: full suite Passed: 1346, Skipped: 17, Failed: 0 (dotnet 9, Release); no telemetry references left (git grep); upstream/main is an ancestor of this branch.

Follow-up, not in this PR: release.yml still uses tag-pinned actions (@v4…); upstream pins to SHAs.

🤖 Generated with Claude Code

builtbyproxy and others added 30 commits October 6, 2026 12:28
…nges, and make archiving part of every release (builtbyproxy#141)

Co-authored-by: t <t@t>
…is renamed (builtbyproxy#127)

Co-authored-by: Wouter Stulp <wouter@peterprint.nl>
…yproxy#128)

* fix: log later seasons of shows Serializd keeps as one season

Jellyfin libraries ordered by TheTVDB split many anime into seasons that Serializd (TMDb order)
lists as one long season, so an episode from Jellyfin season 2 was skipped with "Serializd has
no season 2". When Serializd has season 1 but no season 2, the episode is now logged to season 1
at its absolute number, counted from the earlier Jellyfin seasons. Shows Serializd already splits
into seasons never fall back, and an unknown earlier season length skips instead of guessing.
Local dedup history keeps Jellyfin's numbering so the real-time and catch-up paths agree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: release as 2.10.2 so it doesn't collide with builtbyproxy#127's 2.10.1

Both PRs bumped to 2.10.1; whichever merged second would have shipped no release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: skip single-season fallback episodes past Serializd's season length

The fallback trusted Jellyfin's season lengths alone. When Serializd had not
picked up a new season yet, or the library was missing the end of season 1,
the running number still pointed at a real-looking episode and the watch was
logged to the wrong entry in a public diary. Serializd's /show response
already carries episodeCount per season, so the fallback now requires it and
skips any episode that would land past the end of season 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix: restrict the Seerr connection test to admins

* fix: keep usernames out of the shared sync progress phase

* fix: return a fixed message when the Seerr connection test fails

* fix: refuse /Stats and /History when the caller can't be resolved

* test: guard the shared progress phase against usernames

* fix: run one Serializd watchlist sync at a time and answer 409 while one is going

* refactor: remove the single-account and test-connection endpoints no page calls

* fix: rate-limit the Letterboxd and Serializd login checks per user and server-wide

* test: pin which plugin endpoints are anonymous, signed-in or admin-only

* chore: replace private network details with generic examples and read the deploy target from the environment

* test: widen the progress privacy and endpoint authorization guards

* test: drive the Seerr test failure through a fake transport and tidy the limiter

* fix: cap successful login checks too and let the scheduled Serializd watchlist run wait for a manual one

* chore: release 2.10.4

---------

Co-authored-by: Wouter Stulp <wouter@peterprint.nl>
…er (builtbyproxy#145)

* fix: create Seerr requests as the requesting user so Seerr applies their own approval rights

* fix: give each account its own Serializd watchlist collection, tracked by id instead of by name

* fix: let only admins name watchlist collections and playlists

* fix: hash the account key in the collection record, keep renamed collections unique and say collections are visible server-wide

* refactor: pass the sync's cancellation token to the collection rename and tidy the collection record

* chore: release 2.10.5
…builtbyproxy#146)

* fix: make stored secrets write-only

* fix: carry saved secrets across a rename or an admin's owner change, and verify with the saved password

* fix: show saved passwords, cookies and the Seerr key as Saved instead of filling them in, on both settings pages

* fix: let an admin remove the saved Seerr key, let typed cookies win over the remove box, and match the saved Seerr URL exactly

* fix: keep a failed admin save retryable and share one typed, cleared or kept rule for secrets

* docs: describe the write-only secret rules in CLAUDE.md

* chore: release 2.10.6

---------

Co-authored-by: Wouter Stulp <wouter@peterprint.nl>
* fix: stop the Serializd watchlist sync on a partial read and never record a cancelled episode as failed

* fix: sync each Letterboxd account on the right day, once, and stop giving up on films during outages

* fix: take ratings the plugin writes as the rating sync baseline instead of pushing them later

* docs: describe account-scoped sync history, local viewing dates and the rating import baseline

* fix: address review findings on challenge detection, import supersede, outage rule and watchlist caps

* fix: give up on a film that errors for a week, mark outage runs, and stop watchlist reads that repeat a page

* refactor: detect Cloudflare challenges by page title only and tidy the new tests

* chore: release 2.10.7
* fix: run scheduled tasks at staggered times of day

* fix: retry Serializd cold starts and share one HttpClient

* perf: cap skipped/failed history rows and index per-film lookups

* fix: rewrite history and cache files atomically

* perf: cache Letterboxd TMDb lookups and stop double-throttling them

* perf: reuse the Serializd season cache for watchlist season lookups

* perf: share one HttpClient across Letterboxd API and Seerr clients

* perf: look up library items by TMDb id in the query, not by full scan

* fix: keep every history row the sync and abandon rules read when compacting, and never rewrite a file that did not load cleanly

* perf: pace website lookups after the request instead of alongside it, and let tests reset the film caches

* fix: retry a Serializd write only when the connection never opened, stop an account's catch-up after repeated failures, and keep cookies off the shared clients

* fix: give telemetry its own daily slot and keep a two-day fallback trigger for machines that are off at night

* fix: pause an account's Letterboxd run after repeated Cloudflare blocks, and record films without a TMDb id once

* perf: keep each account's website session and skip an API login that just failed, so real-time events stop logging in again

* perf: link old history rows to user ids in the background, once, instead of during Jellyfin startup

* fix: skip the Letterboxd diary import while another Letterboxd sync is running

* perf: count movies without loading them, and read existing ratings only for users who sync ratings

* fix: let a paused Letterboxd account try one login a day so an outage no longer pauses it for good

* docs: note the cached website session and the narrower rating baseline in CLAUDE.md

* fix: address security review: check an episode's series, stop daily logins after a week, never push before a user's ratings are read, and drop superseded sessions

* fix: address code review: never retry rejected credentials, remember only a definite API refusal, wait for the gate before importing, and test pacing by order

* fix: address performance review: stop a Serializd catch-up only on service failures, and wait for the gate before a Serializd import

* chore: release 2.10.8

---------

Co-authored-by: Wouter Stulp <wouter@peterprint.nl>
* fix: show load and save failures instead of swallowing them

* fix: report the Integrations save result

* fix: keep the in-app page working when the admin settings page is cached, by scoping its lookups and opening the settings page instead

* fix: set the Letterboxd film rating for a review that has only a rating, instead of failing

* fix: on the user page, confirm Remove in the page, report sync, progress, verify and review failures, and offer Review only where it works

* fix: on the admin page, save on top of the stored config, run the TV syncs for every user, label the overview as the admin's own, and report every failure

* fix: address security review: send review errors as one short line, keep the rating title plain, refuse a non-finite rating, and let Retry call only the loaders

* fix: address code-smell review: count a save by its status alone, keep words apart in a rating title, scope the disabled-button style, and pin the dashboard's task keys

* docs: note the rating-only review and the dashboard's scoped lookups in CLAUDE.md

* docs: reword the in-app page fallback note in CLAUDE.md

* chore: release 2.10.9

---------

Co-authored-by: Wouter Stulp <wouter@peterprint.nl>
…#153)

* style: readable primary buttons, faint text and disabled state

* fix: stop restyling Jellyfin's document and following the OS theme

* fix: keep both dashboards inside a phone screen and show each activity row's date there

* fix: follow Jellyfin's light or dark theme, with text and status colours readable in both

* fix: make the dashboards usable by keyboard and screen reader: nav buttons, a rating slider, real dialogs and labelled fields

* fix: send Back to Jellyfin to the server's own base URL, and back through Jellyfin's history when opened in the app

* fix: stop the admin page's progress polling once Jellyfin has dropped the page

* test: pin both dashboards' contrast, scoped styles, phone layout and keyboard markup

* fix: read Jellyfin's theme from the background it paints, which 10.11 keeps off the document while it loads

* fix: find the admin page's dialogs through the page itself, so leaving the page cannot throw

* docs: note the dashboards' theme, dialog and contrast rules in CLAUDE.md

* fix: address security review: never let the browser fill its Jellyfin login into the diary form, and drop typed secrets when the dialog closes

* fix: address code-smell review: a readable gold for links and icons in the light palette, the new admin lookups through the page root, and looser markup tests

* chore: release 2.10.10

---------

Co-authored-by: Wouter Stulp <wouter@peterprint.nl>
* fix: keep email addresses out of the plugin's logs and out of the log bundle sent to the developer

* fix: log only the status and size of a successful Letterboxd review reply, which can echo the review

* feat: let an admin regenerate the telemetry instance id, and remember the answer to the opt-in notice

* refactor: drop the Serializd username field nothing reads

* feat: preview the exact telemetry ping and log bundle before anything is sent, regenerate the telemetry ID, and ask once about telemetry on the admin overview

* docs: describe the telemetry previews, Regenerate ID, the opt-in notice, exact error counts and the masked log bundle as they ship

* docs: note the telemetry previews and email masking rules in CLAUDE.md

* fix: address security review: mask encoded email addresses, keep a quoted review out of a failed post's log, and send the bundle preview's note in a POST body

* fix: address code-smell review: cut review replies older releases logged, leave a very short review's error text intact, widen the email mask, and share one test logger

* chore: release 2.11.0
…iltbyproxy#156)

* fix: cap rate-limit waits at a minute, re-sign the Letterboxd retry, and let a stopped sync cancel its network waits

* fix: post a Serializd episode review on the episode its log goes to, including shows Serializd lists as one season

* fix: never match a Letterboxd TV entry to a movie on the website login path

* fix: serve the full 250-row history page both dashboards ask for

* docs: describe the telemetry start-minute window the code actually uses

* fix: address security review: read a page's TV marker only from its TMDb button, keep the not-a-film marker out of cache reads, and leave usernames out of the rate-limit log

* fix: address code-smell review: count only an explicit TV marker as TV, cancel test waits from inside the request, check the dashboards' history page size against the cap, and tighten the telemetry spec

* fix: address performance review: treat a rate limit longer than the client waits as a block, so a Letterboxd run stops after a few instead of trying every film

* docs: note the rate-limit cap and the cancellation rule in CLAUDE.md

* fix: let the TMDb button decide a TV entry, since live pages label TV entries as movies

* chore: release 2.11.1
* feat: search, episode grouping and older history in the activity list

* feat: group binge runs in the admin Activity log

* feat: page the activity list to its true end, keep one copy of an event seen on two pages, and label the search

* fix: word the account dialog's watchlist toggle for the service picked, and drop the dash from the service names

* test: pin the activity list's search, paging and the account dialog's service wording

* docs: describe the activity search, older history and folded episode runs in the README

* fix: address security review: key a repeated event by its Jellyfin user too, and pin the escaping of a folded episode run

* fix: address code-smell review: keep a folded run to one account, give its true episode range and any failure, cut only by the filtered services, and point an empty search at older history

* chore: release 2.12.0

* test: check the activity pages' history page size settings against the server cap

---------

Co-authored-by: Wouter Stulp <wouter@peterprint.nl>
…uiltbyproxy#158)

* fix: put a review of a film already in the diary on that entry instead of logging a second watch dated today

* test: check live that a review lands on the existing diary entry and the test account is restored

* docs: describe where a review of an already-logged film goes in CLAUDE.md

* fix: address security review: keep a failed update's reply out of the error, read every page of a film's diary entries, date a new entry on the server's local day, and let the live test delete only its own entries

* fix: address code-smell review: read only what the entry lookup needs, refuse a malformed review date, date the tests by the controller's own rule, and make the live test's cleanup failure-safe

* fix: address domain review: hold the film's sync lock while a review is placed, and read the diary a second time before deciding no entry exists

* chore: release 2.12.1

* fix: cache a Letterboxd API token only with its member id, so a sign-in never reads the diary without one

* test: write the member ids the live review test and the client use to its output, and check they match
…byproxy#159)

* refactor: serve one shared dashboard script and stylesheet, stamped and cached per plugin version

* refactor: load the shared script and stylesheet in both dashboards and drop their duplicated code and styles

* feat: say when a review was added to the existing diary entry, and show the server's note for each account

* docs: describe the dashboards' shared script and stylesheet in CLAUDE.md

* fix: address security review: never cache a debug build's shared files for good, and pin the shared escaper and the anonymous scripts' static content

* fix: address code-smell review: read the pages' stamped version from the page itself, anchor the review-notes check on the next method, and drop restated assertions

* perf: address performance review: tag the shared files so a revalidation is answered with 304

* fix: find the admin page's root by id when Jellyfin runs its script without a current script

* chore: release 2.12.2
github-actions Bot and others added 27 commits October 8, 2026 03:17
* fix(worker): close the download open redirect, cap daily log bundles, keep request logs off

* test: give the auth-failure and scheduled-task delegation tests real assertions

* test: run the Serializd history tests serially with the other shared-state tests

* chore: remove the stale build.yaml that no tooling reads

* ci: split release into a read-only build and a minimal publish job that repairs half-finished releases

* ci: pin every workflow action to a full commit SHA

* ci: require the version to rise above main and stay untagged

* ci: let Dependabot watch actions, site npm packages and the other NuGet packages

* docs: describe the safer release pipeline and the worker tests in CLAUDE.md

* test(worker): check every manifest download URL still passes the stricter path rule

* ci: strip multi-line tags from release notes, warn on superseded versions, keep the manifest sorted

* ci: skip the rebuild when repairing a release whose asset is already published

* ci: run the worker tests on every PR
* docs: archive the shipped auth-circuit-breaker OpenSpec change and sync its spec

* docs: state the 10.11.9 SDK floor in CLAUDE.md

* docs: point site, security and issue-template links at the renamed Jellyscribe repo

* docs: update the site for the 10.11.9 floor, optional File Transformation, the current setup flow and the one-way Seerr mirror

* docs: rewrite the README setup and dashboard guide for the current UI, the one-way Seerr mirror, the uncounted manifest and the PR template

* docs: note that downloads are still counted with the GitHub manifest and clarify the breaker archive notes

* docs: link the auth breaker live check to its tracking issue

* docs: correct the install-counter release note that called the fingerprint unlinkable
Jellyfin installs Jellyscribe from fork/manifest.json instead of the upstream repository.
fork/release.sh builds and tests the plugin, publishes the zip as a GitHub release and lists it
in the manifest. Versions are the upstream version plus a fourth number.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit fe6ea36)
Logged episodes and diary entries reached Serializd, but the show never got a status, so the
profile's Shows tab (Currently watching / Watched / ...) stayed empty. The first time an episode
of a show is logged, real time or catch-up, the show is now marked currently watching via
POST /currently_watching. It is sent once per show per account, never for a show whose every
episode in Jellyfin is already played, and a failure there does not fail the episode log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 81fc238)
The sidebar brand block carried a second subtitle line crediting the
upstream author; this fork keeps only the product subtitle there. The
license, README and other credits are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit a31297d)
The README still pointed installs, releases and badges at builtbyproxy, so following
it would install upstream instead of this fork. It now explains the fork, lists what
it adds, gives the fork's plugin repository URL and release steps, and says that
telemetry and log uploads still go to upstream's endpoints. The royalty.dev badge and
.github/FUNDING.yml (GitHub's Sponsor button) are removed since they fund upstream,
not this fork.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 34b7e54)
At 540px and below the When column is hidden, which left phone users with
no idea when anything was logged, and the status chips wrapped into three
or four rows above the table. Show the date in the title's subtitle line
at that width, and make the chip rows one horizontally scrolling strip
using the same rule as the mobile nav.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c1ede4d)
The account modal listed twelve switches in one flat column, mixing the
everyday ones with rarely-touched tuning, and showed Seerr options on
servers with no Seerr configured. Remove deleted an account on one click.

Split the switches into Sync, Watchlist & Seerr, and a collapsed
Advanced section (skip already-synced, stop on first failure, Seerr
backfill). The admin page hides the Seerr rows when no Seerr URL is set,
keeping them in the form so saving preserves their values. Both pages
ask for confirmation before removing an account.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit cef09b9)
The fork drops upstream's telemetry, log upload and install-count mirror, so the
README no longer describes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit b91713b)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 86ed5c2)
This fork is standalone, so it must not upload server log bundles to the
upstream author's diagnostics backend. Drops the PreviewLogs/SendLogs
endpoints, the bundle builder and uploader, and their tests. The local
Logs tab still reads Jellyfin's log files through GetLogs; its elevation
check moves to LetterboxdControllerTests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 75fe02f)
This fork is standalone and should not report usage data to the upstream
author's ingest worker, even opt-in. Removes TelemetryService, its
constants (ingest URL and key), the persisted TelemetryData config, the
weekly TelemetryTask, the preview endpoint and every RecordError /
OnSyncEvent hook in the runners. Logging and error handling around those
hooks are unchanged.

Old config XML files still load: XmlSerializer skips the now-unknown
<Telemetry> element.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 8cd00c1)
RepositoryMigrationService added the upstream author's Cloudflare Worker
manifest URL to Jellyfin's plugin repositories so every catalog poll
could be counted as an install. This fork is standalone and installs
from its own manifest, so drop the migration, its hosted-service
registration, the CatalogMigrationDone flag and their tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit e2261a2)
The backing endpoints are gone, and this standalone fork should not offer
to send usage data or log bundles to the upstream author. Drops the
"Anonymous telemetry" settings panel, the "Send to developer" button and
its confirm box, and the JS that read/saved the Telemetry config and
posted to Telemetry/SendLogs. The Logs tab still shows local log lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 3feefa3)
Only a "currently watching" history key short-circuited the status check,
and a finished show never gets one. So every catch-up walked every
episode of every finished show again, and an unfinished show with new
episodes was walked twice per run (pre-check plus the marking pass).

A show seen as finished now gets a "finished" history key for that
account and is never checked again. The runner also memoises the result
per show for the run. Unfinished shows are still marked currently
watching once per account, and failed marks are still retried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit fc4299a)
The finished marker is now permanent, so a show still airing would get it the moment
you caught up on its latest episode and never show as currently watching again.
Being caught up on a continuing show means still watching it; only a show whose
status is Ended can be finished.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 10dcff5)
A tripped auth breaker or an abandoned film only showed up in the logs
and the activity log, so an admin found out days later that an account
had stopped syncing. Configuring an ntfy topic URL (plus optional token,
encrypted at rest like the Seerr API key) now sends a push when:

- a Letterboxd account's auth breaker opens (high priority), via
  AuthBreaker.NotifyOpenedAsync, which every breaker call site uses
- the scheduled runner gives up on a film after
  MaxConsecutiveSyncFailures failed attempts

Sends never throw into the sync path, and the same event is sent at
most once per 24h. An admin-only Notifications/Test endpoint and a
"Send test" button in Integrations let the admin check the settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 0dd2382)
A show that ended and was fully played in Jellyfin stayed on the
Serializd "currently watching" list forever, or was never marked at all
when it was finished at first sight. Now both the playback handler and
the catch-up runner mark it watched (watched_v2 with every numbered
season id) and take it off currently watching, once per account.

The watched mark is recorded only after watched_v2 succeeds, so a failed
call is retried on the next run. The currently-watching removal only
logs a warning on failure, since the show may never have been on that
list. A show counts as pending until it is marked watched, so finished
shows still trigger a catch-up login, and stop doing so once done.

The marker is "showwatched" because KindWatched already names the
per-episode watched history.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit e221c5a)
Serializd is the main service for most users, but it has no auth
breaker, so a broken login only showed up as a log line on every run.

SerializdApiClient now throws a SerializdAuthException when /login
answers 401/403, while 5xx after the cold-start retries and network
errors keep their existing types, so Render waking up never reads as a
bad password. SerializdServiceFactory catches that exception for the
background paths (catch-up, watchlist, diary import, real-time
playback), which pass the Jellyfin username, and sends a high-priority
ntfy alert. The existing 24h dedupe keeps it to one message a day
while the login stays broken.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit b38117a)
worker/, site/ and openspec/ are upstream's telemetry server, website and planning
docs, none of which this fork runs. build.yaml, deploy.sh, codecov.yml, the root
manifest.json and upstream's docs-deploy, integration, PR-title and version-gate
workflows only served upstream's setup.

release.yml now runs fork/release.sh on every push to main when the version has no
tag yet, using the merged PR's "## Release notes" as the changelog, so a merged PR
ships without a manual step. ci.yml keeps the build/test, the SDK floor check and the
Jellyfin 12 probe. release.sh uses a local dotnet when present, so it runs on GitHub's
runners as well as in Docker locally. The templates, SECURITY.md and CLAUDE.md now
point at this repository.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 8ddf983)
The dashboards printed dates with toLocaleDateString/toLocaleTimeString,
so the format followed each browser's locale (often US month-first) rather
than the European day-first format users expect. One shared formatDate in
jellyscribe.js now renders dd-MM-yy HH:mm (24-hour, local time) for every
history row, group row, the mobile subtitle and the Activity log, and
dd-MM-yy for the "login failing since" date on account cards on both
pages. The review modal's date input keeps its ISO value, which the input
type requires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 9a06060)
… asset

main is protected now, so the old flow (release.sh committing fork/manifest.json to
main) can't work, and the user wants nothing release-related in fork/. Publishing a
release with tag v<version> now runs release.yml: a read-only build job tests the tag
and builds it with the tag as AssemblyVersion, and a separate publish job, which runs
none of the repository's code, attaches the zip and a manifest.json that extends the
previous release's. Jellyfin reads the plugin repository from
releases/latest/download/manifest.json. This also closes the security review's
finding that the release token was exposed to the build. ci.yml gets an explicit
read-only token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit b276ef8)
The fork now sits on builtbyproxy/Jellyscribe v2.12.2 with its own changes
re-applied on top, so the version becomes the upstream version plus the fork's
fourth number.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fork's main is replaced by upstream 2.12.2 plus the fork's own changes
re-applied on top. This merge only links the old fork history so the branch
can go into the protected main through a PR; its tree is this branch's tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@WouterStulp
WouterStulp merged commit 0c9a4f4 into main Oct 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants