LastFrame v1.2 - Built with Claude Code

A self-hosted web dashboard for tracking and managing watch history across multiple users. Browse your libraries, see per-user watch progress, filter by genre or completion status, and automatically delete watched media after a configurable grace period.

https://github.com/shikigamixii/LastFrame/tree/feature/plex

Release Notes — June 21–28, 2026

Everything below applies to both the Plex and Jellyfin builds unless a section or bullet is tagged (Plex only).

New stuff

Added a Recently Added section to the home page, sidebar, and its own "See All" page. Shows new movies and series (not individual episodes) so you can get to user assignments faster. It tracks when a title was first seen rather than relying on Plex's timestamp, so quality upgrades and new episode drops don't keep bumping things back to the top. Default window is 30 days, configurable in settings. Once you save or clear an assignment, the title falls off the list automatically.

Also added "See All" pages for Recently Watched — clicking through now gives you up to 100 items instead of the handful that fit on the home screen.

Security

A few things that should have been caught sooner:

  • Proxy header trust is off by default. X-Forwarded-For was being trusted blindly, which on a direct HTTP setup means anyone can set it to whatever they want — spoofing IPs against the login rate limiter or muddying the audit log. Now you have to explicitly opt in with TRUSTED_PROXY_HOPS.
  • XSS fix in attributes. A quote in a movie title or username could break out of an HTML attribute. Everything going into attributes is properly escaped now.
  • Login no longer leaks valid usernames. Timing differences between "user doesn't exist" and "wrong password" were distinguishable. The check now runs the same bcrypt comparison either way, against a throwaway hash when there's no admin yet.
  • Audit log entries strip control characters, bad request bodies don't blow up the login path anymore, and the standard security headers are in place (X-Frame-Options, X-Content-Type-Options, Referrer-Policy).
  • Replaced bare except: with except Exception: throughout — Ctrl-C was getting swallowed.

Performance

  • Config is cached. config.json was being re-parsed on every single request. It's cached now and only reloads when the file actually changes on disk.
  • HTTP session reuse. Requests to the media server now share one session instead of doing a fresh TLS handshake every time. Makes a meaningful difference since the servers aren't local.
  • SQLite locking. Tuned the database settings — WAL mode, 30-second busy timeout, relaxed fsync. Background sweeps and web requests were stepping on each other more than they needed to.

Bug fixes

  • Accidental season deletion is gone. An empty episode list response used to trigger auto-delete. If the server hiccuped and returned nothing, files would get wiped for no reason. Now you get an empty state with an explicit delete button that requires confirmation.
  • Auto-delete badge was lying. A show with auto-delete enabled showed green "Auto-delete: ON" even when the global toggle was off. It now correctly shows "Paused (global off)" and hides the "Run sweep now" button when it wouldn't actually do anything. Per-show settings are preserved and kick back in when the global toggle is re-enabled.

Managed-user sweep & debugging (Plex only)

The sweep is off by default (interval is 0). It works in theory, but most servers — especially seedbox-hosted ones — reject the tokens that get minted, so it was just burning API calls and database writes for nothing. The on-demand debug endpoint is still there if you want to test your setup.

On the token side: proper client identifiers and product headers are now sent, the legacy XML endpoint is tried first (it returns tokens the server actually accepts), falling back to v2 if needed, with a brief pause between cold mints to avoid getting rate-limited by plex.tv. The server's token list also gets refreshed before each sweep.

Token minting now logs the HTTP status, which endpoint it hit, and a response snippet — so when a mint fails, you actually know what plex.tv said.

Debugging

  • Per-item webhook events. New endpoint to pull webhook events for a specific item, which makes it a lot easier to figure out why something is or isn't getting marked watched. Jellyfin already had this; Plex caught up this week.
  • Errors go to the logs. Unhandled exceptions now print to stderr with a full traceback so they actually show up in container logs.

Docs & housekeeping

  • Documented TRUSTED_PROXY_HOPS in the README.
  • (Plex only) Wrote up the known gap where a managed user manually marking something watched on their end can't be detected through any Plex signal.
  • Added a note that the media servers are remote, not LAN, so the codebase stops reaching for fixes that assume local network access.
  • Cleaned up the project rules.
reddit.com
u/luzkidd — 7 days ago

LastFrame v1.2 - Built with Claude

edit: I specifically labeled what only applies to Plex.

A self-hosted web dashboard for tracking and managing watch history across multiple users. Browse your libraries, see per-user watch progress, filter by genre or completion status, and automatically delete watched media after a configurable grace period.

https://github.com/shikigamixii/LastFrame/tree/feature/jellyfin

Release Notes — June 21–28, 2026

Everything below applies to both the Plex and Jellyfin builds unless a section or bullet is tagged (Plex only).

New stuff

Added a Recently Added section to the home page, sidebar, and its own "See All" page. Shows new movies and series (not individual episodes) so you can get to user assignments faster. It tracks when a title was first seen rather than relying on Plex's timestamp, so quality upgrades and new episode drops don't keep bumping things back to the top. Default window is 30 days, configurable in settings. Once you save or clear an assignment, the title falls off the list automatically.

Also added "See All" pages for Recently Watched — clicking through now gives you up to 100 items instead of the handful that fit on the home screen.

Security

A few things that should have been caught sooner:

  • Proxy header trust is off by default. X-Forwarded-For was being trusted blindly, which on a direct HTTP setup means anyone can set it to whatever they want — spoofing IPs against the login rate limiter or muddying the audit log. Now you have to explicitly opt in with TRUSTED_PROXY_HOPS.
  • XSS fix in attributes. A quote in a movie title or username could break out of an HTML attribute. Everything going into attributes is properly escaped now.
  • Login no longer leaks valid usernames. Timing differences between "user doesn't exist" and "wrong password" were distinguishable. The check now runs the same bcrypt comparison either way, against a throwaway hash when there's no admin yet.
  • Audit log entries strip control characters, bad request bodies don't blow up the login path anymore, and the standard security headers are in place (X-Frame-Options, X-Content-Type-Options, Referrer-Policy).
  • Replaced bare except: with except Exception: throughout — Ctrl-C was getting swallowed.

Performance

  • Config is cached. config.json was being re-parsed on every single request. It's cached now and only reloads when the file actually changes on disk.
  • HTTP session reuse. Requests to the media server now share one session instead of doing a fresh TLS handshake every time. Makes a meaningful difference since the servers aren't local.
  • SQLite locking. Tuned the database settings — WAL mode, 30-second busy timeout, relaxed fsync. Background sweeps and web requests were stepping on each other more than they needed to.

Bug fixes

  • Accidental season deletion is gone. An empty episode list response used to trigger auto-delete. If the server hiccuped and returned nothing, files would get wiped for no reason. Now you get an empty state with an explicit delete button that requires confirmation.
  • Auto-delete badge was lying. A show with auto-delete enabled showed green "Auto-delete: ON" even when the global toggle was off. It now correctly shows "Paused (global off)" and hides the "Run sweep now" button when it wouldn't actually do anything. Per-show settings are preserved and kick back in when the global toggle is re-enabled.

Managed-user sweep & debugging (Plex only)

The sweep is off by default (interval is 0). It works in theory, but most servers — especially seedbox-hosted ones — reject the tokens that get minted, so it was just burning API calls and database writes for nothing. The on-demand debug endpoint is still there if you want to test your setup.

On the token side: proper client identifiers and product headers are now sent, the legacy XML endpoint is tried first (it returns tokens the server actually accepts), falling back to v2 if needed, with a brief pause between cold mints to avoid getting rate-limited by plex.tv. The server's token list also gets refreshed before each sweep.

Token minting now logs the HTTP status, which endpoint it hit, and a response snippet — so when a mint fails, you actually know what plex.tv said.

Debugging

  • Per-item webhook events. New endpoint to pull webhook events for a specific item, which makes it a lot easier to figure out why something is or isn't getting marked watched. Jellyfin already had this; Plex caught up this week.
  • Errors go to the logs. Unhandled exceptions now print to stderr with a full traceback so they actually show up in container logs.

Docs & housekeeping

  • Documented TRUSTED_PROXY_HOPS in the README.
  • (Plex only) Wrote up the known gap where a managed user manually marking something watched on their end can't be detected through any Plex signal.
  • Added a note that the media servers are remote, not LAN, so the codebase stops reaching for fixes that assume local network access.
  • Cleaned up the project rules.
reddit.com
u/luzkidd — 7 days ago

Claude Code made an app for me - LastFrame

So I may get flack for this because "it's made with AI" but honestly this was something that helped a non-coder fill a gap that jellyfin lacked.

A bit of a copy and paste but I wanted to share a project I've been working on. The main motivation was that Jellyfin lacks the ability to click on a movie or show to see who has watched it. A feature that plex supports. But building on top of that this app lets you assign users to specific media so you can track whether everyone has watched a given title.

You can either stop there or utilize the delete function that's built in. Once assignments are set, you can either manually delete content or enable auto-delete at the library or media level. In the settings you can see that auto-delete is on but not for the libraries which is intentional because at the moment I only want certain items to auto-delete.

Took a feature from Tataulli so you're also able to see what's currently playing.

I have an idea for a future feature to display new library items — such as a new series or movie — so you can set assignments right away.

I went for a minimalist approach, as I didn't want anything too cluttered.

I sacrificed some of media while testing this so at this point media is safe and won't be randomly deleted. I'd love to have some testers if possible to let me know if certain things won't load or if something takes too long to perform an action. I'm open to any other possible features too.

I have branches for both Plex and Jellyfin:
https://github.com/shikigamixii/LastFrame/tree/feature/plex

Edit: I'm open to a name change if LastFrame doesn't sit well

u/luzkidd — 15 days ago

LastFrame

Another edit: This project was used with Claude code.

Sorry for the repost I had to edit one of the photos (it had info in it) and didn't know how without reposting.

Hi everyone! I wanted to share a project I've been working on. The main motivation was that Jellyfin lacks the ability to click on a movie or show to see who has watched it. Essentially, this app lets you assign users to specific media so you can track whether everyone has watched a given title. Once assignments are set, you can either manually delete content or enable auto-delete at the library or media level. You're also able to see what's currently playing.

I have an idea for a future feature to surface new library items — such as a new series or movie — so you can set assignments right away.

I went for a minimalist approach, as I didn't want anything too cluttered.

I'd love to have some testers if possible — I even sacrificed some media on my server to make sure everything worked properly.

I have branches for both Plex and Jellyfin:
https://github.com/shikigamixii/LastFrame/tree/feature/jellyfin

Edit: I'm open to a name change if LastFrame doesn't sit well

u/luzkidd — 17 days ago

Watch History

Hey everyone!

So I'm working on a personal project for myself using "AI Slop" to create a dashboard where I can view who watched what with the ability to assign users to a certain media and delete directly from the dashboard. I've tried other tools that don't seem to be as detailed or provides that additional control and it's been years since i've tried jellyfin just to see that they still haven't implemented a watch history similar to plex. Here are some screenshots. kinda looking for some feedback to help me kinda polish this a bit better. I'm actively making changes to this. the pink markouts are usernames

u/luzkidd — 1 month ago