dtourolleandClaude Opus 5 8027fd5fac feat(repository): a route table and resolved server capabilities
Endpoints were 57 inline format! literals with their query strings baked in at
the point of use. That is workable against exactly one server and hostile to
anything else: a second route shape would mean a conditional at every one of
them. They now live in repository/endpoints.rs, one function each, taking
&ServerCapabilities.

Two things fall out of the move:

  - A small Endpoint builder replaces the manual ?/& juggling, so a double or
    trailing separator is structurally impossible rather than something four
    assertions in a deleted test file used to watch for.
  - Both user-scoped route shapes (/Users/{uid}/Items and /Items?userId=) are
    built and tested, though nothing selects the second yet. The family still
    works on 12.0, so migrating is optional; having both means it is a one-line
    change if 13.0 removes them, as the newly written removal policy allows.

ServerCapabilities is resolved once per connection from the version the server
already reported at connect. The version-to-flags mapping lives in exactly one
function and nothing else in the crate compares a version number: a `version < N`
at the point of use re-derives a domain fact where it is consumed, is unreadable
by its second occurrence, and cannot express a backport.

An unrecognised version resolves forward to the newest known generation rather
than being refused, because refusing would make every release expire the moment
the server upgrades. Only a version below the floor is refused.

This commit also carries the two fixes that are NOT capability branches, because
they live in the same files:

  - Authorization replaces X-Emby-Authorization, and ApiKey replaces the api_key
    query parameter. Jellyfin 12.0 disables both legacy spellings by default and
    a migration flips them on upgraded servers too, so this is what actually
    breaks against 12.0. The header value this app already built was always the
    correct MediaBrowser scheme, and both new spellings are ungated on 10.11.x —
    so it is a rename, not a branch. The query-parameter spelling is load-bearing
    rather than cosmetic: stream URLs go to mpv, ExoPlayer and the webview's
    <video>, none of which can send a header.
  - A type-filtered listing now states Recursive explicitly. 12.0 defaults it to
    true for a library parent with IncludeItemTypes where 10.11 returned
    immediate children, so the identical request returned a different result set
    with nothing in the response to say which rule applied. The value sent is the
    one that shipped, so this is a compatibility fix and not a silent behaviour
    change.

A structural test refuses any deprecated auth spelling reaching a request
builder, verified to fail when one is reintroduced. Behaviour is otherwise
preserved: the four previous endpoint builders become test-only shims over the
new table, so the ~20 existing tests encoding DR-116/DR-212/DR-257 now exercise
the production path rather than being deleted.

TRACES: UR-085 | IR-035, DR-279, DR-280, DR-287, DR-288

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 20:09:34 +02:00
2026-08-27 17:58:06 +02:00
2026-01-26 22:21:54 +01:00
2026-09-07 22:29:40 +02:00
2026-09-07 22:29:40 +02:00
2026-01-26 22:21:54 +01:00
2026-01-26 22:21:54 +01:00

JellyTau logo
JellyTau

A cross-platform Jellyfin client built with Tauri, SvelteKit, and TypeScript.

Business logic lives in a Rust backend; a UI-rich Svelte frontend handles presentation and talks to it over Tauri's IPC. Targets Linux (libmpv) and Android (ExoPlayer).

Getting Started

This project uses bun as its package manager.

# Activate the Rust environment (fish shell)
source "$HOME/.cargo/env.fish"

# Install dependencies
bun install

# Run in development
bun run tauri dev

# Type-check the frontend
bun run check

# Build for Linux
bun run tauri build

# Build for Android
bun run tauri android build

For the full set of build, test, and Android helper scripts, see scripts/README.md.

Documentation

Topic Location
Architecture overview & subsystem docs docs/architecture/
Requirements, traceability & technical debt docs/requirements.md
Build & release process docs/build/build-release.md
Docker builds docs/build/docker.md
Traceability tooling & CI docs/traceability.md, docs/traceability-ci.md
Release checklist docs/release-checklist.md
UX flows docs/ux-flows.md
CI operations (builder image, secrets, runner) docs/build/ci-operations.md

Contributing

CONTRIBUTING.md covers the setup, the gates a change has to pass, and the two rules that catch people out (bug fixes start with a failing test; Jellyfin's taxonomy stays in Rust). Please also read the Code of Conduct.

Found a security problem? Do not open an issue — see SECURITY.md.

Verifying a download

Every release publishes SHA256SUMS covering all of its artifacts, plus an SBOM of what went into the build:

sha256sum -c SHA256SUMS

Desktop builds update themselves from Settings → Updates, verifying each payload against JellyTau's signing key before installing. Android installs are handled by the system installer, so the app links to the releases page instead.

VS Code + Svelte + Tauri + rust-analyzer.

License

MIT

S
Description
A jellyfin client with Tauri
Readme MIT
205 MiB
2026-09-07 20:30:29 +00:00
Languages
Rust 52%
TypeScript 25.1%
Svelte 16.1%
Kotlin 4.6%
Shell 1.6%
Other 0.5%