Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
272 commits
Select commit Hold shift + click to select a range
a38bf57
feat(provider): persist source identity and isolate stale operations
sachk Sep 20, 2026
d04bb7f
fix(provider): reject unavailable host extensions and UI imports
sachk Sep 20, 2026
cb00dc8
fix(provider): load bundled modules through the worker registry
sachk Sep 21, 2026
68097fb
fix(build): share generated provider resources across consumers
sachk Sep 21, 2026
20991bb
feat(provider): host scoped QML actions with bounded native list models
sachk Sep 21, 2026
34bd3a2
fix(bench): include page construction and record measurement context
Sep 21, 2026
f5c18af
feat(provider): decode listing pages into source-scoped native data o…
Sep 21, 2026
0f65470
docs(provider): prioritize real Jellyfin A/B integration and handoff
Sep 21, 2026
72bad8f
feat(api): wire portable JavaScript Jellyfin adapter and backend sele…
sachk Sep 21, 2026
c112159
fix(providers): update bundled spool.jellyfin with resume endpoint fix
sachk Sep 21, 2026
b8fb532
fix(platform): version-scope qml disk cache and support SAM launch pa…
sachk Sep 21, 2026
c5c1a3c
feat(benchmark): add head-to-head provider benchmark option
sachk Sep 21, 2026
0bfb1d1
test(benchmark): harden provider benchmark against single-step reject…
sachk Sep 21, 2026
513234e
feat(provider): add safe provider package unpacking and validation
sachk Sep 21, 2026
52941eb
feat(provider): add package installation and dynamic module scanning …
sachk Sep 21, 2026
08a912a
feat(shell): add provider onboarding screen and update account picker…
sachk Sep 21, 2026
fedc45f
chore(release): bump version to 0.8.0
sachk Sep 21, 2026
0c80616
docs: add portable provider implementation brief
sachk Sep 21, 2026
ad6fcb6
fix(provider): use self-contained puff decompressor and eliminate ext…
sachk Sep 22, 2026
605a1c2
fix(platform): compile DesktopPlaybackRuntime into core target for li…
sachk Sep 22, 2026
2cad1cf
fix(tests): run provider-qml-cache with offscreen QPA platform in hea…
sachk Sep 22, 2026
1b6a8ea
fix(android): retry Gradle packaging on transient network failures
sachk Sep 22, 2026
ef21637
feat(provider): switch jellyfin to js backend and add stream quality …
sachk Sep 22, 2026
06ad9e3
refactor(provider): remove legacy native jellyfin backend and streaml…
sachk Sep 22, 2026
a61acca
refactor(provider): replace native Jellyfin with multi-account provid…
sachk Sep 22, 2026
79ab24f
fix(provider): close races found while rewriting the provider tests
sachk Sep 22, 2026
80b3cce
test(provider): rewrite provider tests for the multi-account platform
sachk Sep 22, 2026
49d6d3c
chore(provider): pin spool.jellyfin 0.2.0 built from spool-jellyfin@6…
sachk Sep 22, 2026
5830b95
docs(sdk): describe provider API 0.2, packages, screens and publishing
sachk Sep 22, 2026
4074042
fix(shell): issues found running the app against a real Jellyfin
sachk Sep 22, 2026
46b5ade
fix(build): key the QML disk cache on the bundled providers
sachk Sep 22, 2026
fc38cbc
test(provider): opt-in live Jellyfin test through registry and hub
sachk Sep 22, 2026
f8eb2d4
chore(provider): pin spool.jellyfin 0.2.0 built from spool-jellyfin@e…
sachk Sep 22, 2026
760ad1b
chore(provider): pin the published spool.jellyfin v0.2.0 release asset
sachk Sep 22, 2026
2a12aae
test(provider): wait for accounts to finish starting before a hot ins…
sachk Sep 22, 2026
d61a498
fix(provider): list every installed provider; missing operations are …
sachk Sep 22, 2026
f29c1a8
docs: one providers.md for the platform as built; AGENTS.md seam section
sachk Sep 22, 2026
a629a56
fix(bench): start the route walk after accounts restore; empty home i…
sachk Sep 22, 2026
6aba8d1
fix(android): drive the system media controls through ApplicationHooks
sachk Sep 23, 2026
2cb3e45
fix(app): fetch the autoplay item through the catalog
sachk Sep 23, 2026
818d2d1
feat(provider): choose where providers may come from at build time
sachk Sep 23, 2026
2e6d718
fix(package-audit): resolve libraries by file name, and run the test
sachk Sep 23, 2026
b9d6ed7
fix(appimage): bundle glibc so Linux packages start on any distro
sachk Sep 23, 2026
0f1d6b4
test(package-audit): register the ELF audit test on Linux only
sachk Sep 23, 2026
02ecf9f
fix(ui): draw a text caret that can be seen on every screen
sachk Sep 23, 2026
543f6bd
feat(search): search every server at once through the fewest accounts
sachk Sep 23, 2026
6b0c4eb
refactor: call the app Spool everywhere
sachk Sep 23, 2026
a771a4c
fix(provider): pass every library filter to providers as one object
sachk Sep 23, 2026
ceba9bf
refactor(ui): sparser provider screens, no subtitles that repeat the …
sachk Sep 23, 2026
ac97b88
feat(provider): bundle Emby and Plex, and Jellyfin 0.2.1
sachk Sep 23, 2026
075115c
refactor: remove code nothing calls any more
sachk Sep 23, 2026
e568260
docs(providers): search across users of a server, and the bundled pro…
sachk Sep 23, 2026
4df3702
docs(agents): Emby and Plex are bundled providers too
sachk Sep 23, 2026
ec68afa
fix(webos): rebuild Qt with current cursor patch
sachk Sep 26, 2026
e8f7aa7
feat(providers): restore threaded connection speed testing
sachk Sep 26, 2026
0fcea88
feat(details): position episode rails at viewing progress
sachk Sep 26, 2026
6192a5d
feat(providers): probe media ranges and warm all packaged QML
sachk Sep 26, 2026
993546d
chore(providers): bundle published Plex Emby and Jellyfin releases
sachk Sep 26, 2026
3a10a12
fix(artwork): preserve inherited provider image ownership
sachk Sep 27, 2026
f10f756
fix(ui): scale and wrap provider update feedback
sachk Sep 27, 2026
aa80424
feat(dev): discover sibling providers for bundled-only local builds
sachk Sep 27, 2026
9b86ccb
feat(providers): complete optional parity extensions and account flows
sachk Sep 28, 2026
40c9c79
feat(release): ship 0.8.2 with guided provider installs
sachk Sep 28, 2026
cfa44d5
test(providers): load bundled modules by resource filename
sachk Sep 28, 2026
95586fd
test(providers): compare canonical checkout paths on macOS
sachk Sep 28, 2026
60b8832
test(settings): await applied snapshot after account switch
sachk Sep 28, 2026
5b4272d
feat(providers): refine discovery, sign-in and contextual device cont…
sachk Sep 28, 2026
b2b0259
fix(ui): size the device dropdown to its controls
sachk Sep 28, 2026
0f641d0
chore(release): prepare Spool 0.8.3
sachk Sep 28, 2026
bd2e118
test(settings): allow the first account to finish during fixture loading
sachk Sep 28, 2026
94bcc76
fix(discovery): allow declared LAN probes during provider login
sachk Sep 28, 2026
46ea8ae
test(providers): allow cold Windows fixtures time to start
sachk Sep 28, 2026
774a378
perf(player): load trickplay sheets only when previewed
sachk Sep 30, 2026
8c42287
perf(ui): defer folder dialogs and avoid redundant settings work
sachk Sep 30, 2026
c98a2b4
feat(providers): compile shared forms and configure local media libra…
sachk Sep 30, 2026
8aea816
fix(ui): distinguish login actions with blue button fills
sachk Sep 30, 2026
d9e26ed
fix(artwork): preserve image metadata across QML value boundaries
sachk Sep 30, 2026
6f39582
fix(render): respect desktop SDR mode and matching video targets
sachk Sep 30, 2026
2c4122f
fix(artwork): isolate authenticated playback previews by account
sachk Sep 30, 2026
513ddff
fix(browse): prioritize visible artwork and invalidate removed accoun…
sachk Sep 30, 2026
79ae33f
fix(player): resume a stream cut off mid-item instead of advancing
sachk Sep 30, 2026
d5c6f08
test: drop restated schema declarations and revive the pinned-archive…
sachk Sep 30, 2026
9847834
feat(providers): clearer sign-in codes and a roomier provider list
sachk Sep 30, 2026
423aea6
feat(browse): offer HDR where a server can filter by it
sachk Sep 30, 2026
6bf8e0f
chore(providers): bundle Jellyfin 0.2.7, Emby 0.1.3 and Plex 0.1.4
sachk Sep 30, 2026
23c960d
fix(webos): forward mpv_render_context_get_info through the lazy libm…
sachk Sep 30, 2026
8d0737c
feat(player): show external subtitle files during direct play
sachk Sep 30, 2026
fa614ba
feat(ui): rearrange libraries and improve sign-in and search
sachk Sep 30, 2026
818b83e
chore(release): bundle released providers for Spool 0.8.4
sachk Sep 30, 2026
1ccfebd
fix(ui): keep server badges within media cards
sachk Sep 30, 2026
f8df0ad
test(providers): compare canonical local folder identity on macOS
sachk Sep 30, 2026
4609f35
fix(artwork): gate buffered grid requests by model row
sachk Sep 30, 2026
651a408
test(runtime): isolate disk caches for mutable provider fixtures
sachk Sep 30, 2026
6bca6dc
fix(runtime): measure Windows script budget by worker CPU time
sachk Sep 30, 2026
e0c4269
test(collections): keep concurrent removal fixture pending
sachk Sep 30, 2026
1027df3
chore(release): prepare Spool 0.8.8
sachk Sep 30, 2026
a6bff64
test(settings): control bootstrap and write response barriers
sachk Sep 30, 2026
5b4ccd5
chore(release): prepare Spool 0.8.9
sachk Sep 30, 2026
b979bd5
test(artwork): report preview request failures without credentials
sachk Sep 30, 2026
ba8099b
fix(artwork): preserve numeric account scopes in preview URLs
sachk Sep 30, 2026
f43a374
fix(release): ship FFmpeg 9.0.2 with scoped upstream VEX evidence
sachk Oct 1, 2026
fbd4135
perf(trickplay): retain sprite textures and prefetch directional prev…
sachk Oct 4, 2026
cf02bc3
fix(providers): restore playback continuity and library controls
sachk Oct 5, 2026
3661778
chore(release): prepare 0.8.12 with published preview providers
sachk Oct 5, 2026
41b4536
fix(trickplay): use the installed Qt bundled JPEG header
sachk Oct 5, 2026
9161695
fix(playback): preserve quality choices and add explicit URL diagnostics
sachk Oct 6, 2026
9fd8d01
feat(providers): gate Apple App Store bundles on curated approval
sachk Oct 6, 2026
34bc03e
feat(provider): add filtered lazy native logging
sachk Oct 6, 2026
5f3e7b8
feat(apple): add sandbox Keychain audio lifecycle and media controls
sachk Oct 6, 2026
cf98049
feat(providers): gate Apple App Store bundles on curated approval
sachk Oct 6, 2026
3308994
feat(playback): add global seek preview controls and diagnostics
sachk Oct 6, 2026
466e95a
feat(provider): negotiate finite original and server-transcoded downl…
sachk Oct 6, 2026
e904a79
build(apple): cross-build pinned static media closure
sachk Oct 6, 2026
ffef93c
feat(tvos): add source-built UIKit player and Siri Remote navigation
sachk Oct 6, 2026
49c02c6
fix(apple): reject external mpv configuration in App Store builds
sachk Oct 6, 2026
ab47950
test(previews): preserve authentication sequence during opt-out coverage
sachk Oct 6, 2026
bc17779
fix(player): keep fullscreen transitions off mpv render waits
sachk Oct 6, 2026
5f1dadd
feat(settings): simplify sync and improve provider recovery UX
sachk Oct 6, 2026
797de1a
fix(build): fetch pinned FreeType from reachable official mirror
sachk Oct 6, 2026
bf5ecad
fix(build): fetch pinned FreeType from reachable official mirror
sachk Oct 6, 2026
3f87df2
feat(downloads): stream persistent media for native offline playback
sachk Oct 6, 2026
18d331a
fix(tvos): use Xcode tools and ignore repeated play-pause releases
sachk Oct 6, 2026
76e8cdd
fix(apple): resolve TLS dependencies inside target prefix
sachk Oct 6, 2026
e835cbe
test(provider): apply exact logging category rules
sachk Oct 6, 2026
b90b690
fix(apple): provide native compilers for cross-build generators
sachk Oct 6, 2026
b21281e
fix(tvos): restore UIKit metadata paths in pinned Qt sources
sachk Oct 6, 2026
240567c
fix(downloads): cancel scoped provider pickers before renegotiation
sachk Oct 6, 2026
cb80206
fix(apple): bound subtitle dependencies to target font stack
sachk Oct 6, 2026
34c75f1
fix(tvos): omit unavailable unused Qt permission plugins
sachk Oct 6, 2026
9d9e821
feat(spoolet): control native downloads through bounded commands
sachk Oct 6, 2026
ad4fef9
fix(provider): redact late cookie and quoted authorization credentials
sachk Oct 6, 2026
82d1fc4
test(apple): exercise native GLES scene graph in launch smoke
sachk Oct 6, 2026
7fd4847
feat(ios): define audited SDK TLS and VideoToolbox codec policy
sachk Oct 6, 2026
7132dc8
fix(tvos): respect unavailable trash API and audit SDK media policy
sachk Oct 6, 2026
fb7850a
refactor(providers): retire frozen-host compatibility contracts
sachk Oct 6, 2026
9fda706
fix(apple): compile FFmpeg generators for the build host
sachk Oct 6, 2026
fabd536
fix(tvos): exclude unavailable UIKit document icon lookup
sachk Oct 6, 2026
646f269
fix(tvos): select UIKit proxy APIs and complete target dependency roots
sachk Oct 6, 2026
6898088
fix(downloads): distinguish viewer cancellation from server failure
sachk Oct 6, 2026
5b964e9
chore(release): prepare 0.9.0 with published compatible providers
sachk Oct 6, 2026
69dd128
fix(tvos): exclude unused fork-based QtTest runtime
sachk Oct 6, 2026
e163fb7
docs(tvos): record actual UIKit source-port validation blocker
sachk Oct 6, 2026
d12f8a9
fix(apple): gate debugger subprocesses on Qt process support
sachk Oct 6, 2026
1cd90bd
fix(tvos): use layout geometry instead of unavailable rotation APIs
sachk Oct 6, 2026
d2c73fd
fix(tvos): exclude unavailable iOS CALayer EDR observer
sachk Oct 6, 2026
6562805
fix(tvos): use supported palette and remote-only UIKit input APIs
sachk Oct 6, 2026
0b98436
fix(android): use raw JNI wrapper for download destinations
sachk Oct 6, 2026
3eab1fa
chore(providers): bundle all five compatible curated releases
sachk Oct 6, 2026
ddab608
fix(tvos): inventory flat UIKit app bundles in Qt SPDX metadata
sachk Oct 6, 2026
9d6b5ba
fix(apple): build TLS libraries without prohibited CLI server process
sachk Oct 6, 2026
b3f7c60
build(tvos): verify device target and real audio credentials consumers
sachk Oct 6, 2026
28a1a02
fix(tvos): omit unused QCoro QtTest wrappers from target closure
sachk Oct 6, 2026
571b6c1
fix(webos): materialize remote arguments before coroutine suspension
sachk Oct 6, 2026
17a8cea
fix(build): avoid unreachable geo-selected Qt source mirror
sachk Oct 6, 2026
04e654d
fix(tvos): use supported device frameworks and patched native import …
sachk Oct 6, 2026
c97324c
fix(tvos): apply shared source patches with GNU patch
sachk Oct 6, 2026
86cac40
fix(tvos): share canonical import scan exclusions with native smoke t…
sachk Oct 6, 2026
0e843ea
fix(tvos): restrict IOKit machine identity queries to macOS
sachk Oct 7, 2026
7aec730
fix(tvos): compile asset catalogue and filter native startup failure …
sachk Oct 7, 2026
f8aee9c
fix(tvos): retain shared WheelHandler type without unavailable native…
sachk Oct 7, 2026
9500c67
test(tvos): anchor renderer consumer to actual UIKit surface geometry
sachk Oct 7, 2026
f04ecaa
test(tvos): exercise real viewport resize on fixed fullscreen native …
sachk Oct 7, 2026
220bb48
test(tvos): report native secure-store failures without credential ou…
sachk Oct 7, 2026
5315fef
feat(release): publish validated unsigned tvOS device IPA
sachk Oct 6, 2026
06b7946
docs(tvos): align source signing with configurable bundle identity
sachk Oct 6, 2026
0d03925
fix(tvos): include tasktree host tools and scanner cache policy
sachk Oct 6, 2026
ffe715d
fix(tvos): install GNU patch for native scanner source repair
sachk Oct 6, 2026
562ac85
feat(release): audit tvOS device IPA and publish complete metadata
sachk Oct 6, 2026
a0dad81
fix(release): keep unsigned TV metadata within static site budget
sachk Oct 6, 2026
4321696
test(tvos): preserve native renderer failure geometry and pixels
sachk Oct 7, 2026
d918e29
merge: integrate final 0.9.0 host and reviewed provider pins into tvOS
sachk Oct 7, 2026
13fd72b
feat(tvos): integrate native Apple TV source and release pipeline
sachk Oct 7, 2026
ddb551f
fix(tvos): sign simulator consumers with real Keychain entitlements
sachk Oct 7, 2026
105821e
fix(tvos): embed simulator Keychain XML and DER entitlement sections
sachk Oct 7, 2026
9511331
fix(player): restore shared GL defaults at legacy framebuffer boundaries
sachk Oct 7, 2026
143ae86
test(player): capture native video only after real window presentation
sachk Oct 7, 2026
2a51932
test(tvos): launch each native consumer in a distinct process
sachk Oct 7, 2026
98e4097
test(player): enter native event loop for presented frame consumers
sachk Oct 7, 2026
bd6692e
test(tvos): use finite media for native renderer lifecycle proof
sachk Oct 7, 2026
568d6d5
test(tvos): require fresh atomic native credential result receipts
sachk Oct 7, 2026
c7a77bb
fix(player): honor Qt framebuffer scope and GUI-owned handoff acknowl…
sachk Oct 7, 2026
48006dd
feat(webos): make offline media downloads an explicit storage opt-in
sachk Oct 7, 2026
ae58251
feat(provider): define current format-3 capability SDK contract
sachk Oct 7, 2026
f01342b
docs(provider): specify native facility capability guards
sachk Oct 7, 2026
6c84a47
feat(desktop): isolate application storage with an explicit data dire…
sachk Oct 7, 2026
7646add
refactor(provider): replace negotiation with current account capabili…
sachk Oct 7, 2026
6185eaa
test(provider): support unified harness SDK fixture entrypoint
sachk Oct 7, 2026
d5be11e
build(provider): bundle current working capability packages
sachk Oct 7, 2026
51d0cb0
docs(provider): document current package promotion and unified tests
sachk Oct 7, 2026
55f6e04
fix(provider): bundle Qt-compatible current capability offers
sachk Oct 7, 2026
7081526
docs(provider): record executed current-contract consumer proof
sachk Oct 7, 2026
7e86394
refactor(provider): integrate the sole current capability contract
sachk Oct 7, 2026
cd1845e
fix(provider): clear joined group on owning account capability loss
sachk Oct 7, 2026
eac1893
test: unify isolated native suites and real cross-platform app journeys
sachk Oct 7, 2026
a20723b
Merge branch 'refactor/provider-seam' into test/unified-e2e
sachk Oct 7, 2026
ad18860
test(provider): require native activation for foreground integration
sachk Oct 7, 2026
57ded7a
feat(providers): group viewers into profile sets with a persisted sta…
sachk Oct 7, 2026
ca7c862
feat(ui): rebuild Profiles & servers around profile sets
sachk Oct 7, 2026
72713f3
refactor(provider): replace the educational decoder with official lib…
sachk Oct 7, 2026
06da86d
feat(profiles): complete startup, setup reuse and cancellable account…
sachk Oct 7, 2026
27c013c
Merge commit '72713f31' into feature/profile-session-ux
sachk Oct 7, 2026
a94ea89
test: retain crash trees and exercise isolated native admission
sachk Oct 7, 2026
7a77507
refactor(provider): replace the educational decoder with official lib…
sachk Oct 7, 2026
f44e4a2
fix(player): pin fully initialized scaler lookup texture channels
sachk Oct 7, 2026
7736968
test: preserve inconclusive live sockets and require ownership coverage
sachk Oct 7, 2026
468fd46
fix(player): pin fully initialized scaler lookup texture channels
sachk Oct 7, 2026
a7a7824
feat(profiles): expose actionable setup and private current SDK compl…
sachk Oct 7, 2026
8434fc1
chore(sdk): include standalone SDK distribution license
sachk Oct 7, 2026
c67e130
build(profiles): bundle immutable current UX provider packages
sachk Oct 7, 2026
777ce58
fix(profiles): preserve private setup and selected onboarding viewer
sachk Oct 7, 2026
d8606cf
Merge branch 'refactor/provider-seam' into feature/profile-session-ux
sachk Oct 7, 2026
10fbb68
chore(providers): pin exact published current-capability releases
sachk Oct 7, 2026
940f3bd
chore(providers): pin exact published current-capability releases
sachk Oct 7, 2026
653b7b3
test: complete real app journeys and hardened native supervision
sachk Oct 8, 2026
4a1eea3
fix(tools): isolate foreign git namespaces in push hooks
sachk Oct 8, 2026
16ecb05
test: integrate isolated traditional and graphics end-to-end suites
sachk Oct 8, 2026
e8820ab
test: compact independent compressed fixture byte tables
sachk Oct 8, 2026
938e115
test: compact independent compressed fixture byte tables
sachk Oct 8, 2026
a1bc17b
test: repair portable fixtures and native bundle ownership
sachk Oct 8, 2026
a68fb87
fix(ci): integrate deterministic dependency and native resource owner…
sachk Oct 8, 2026
0f25b00
test: instrument official libzstd in sanitizer builds
sachk Oct 8, 2026
7d50396
test: preserve mobile owners and real platform consumers
sachk Oct 8, 2026
e5cee50
fix: make sign-in errors visible and accessible
sachk Oct 8, 2026
f9884fc
fix: preserve native test fixtures and platform transitions
sachk Oct 8, 2026
8b44893
fix: admit Cocoa patch through whitespace gate
sachk Oct 8, 2026
1ca339d
fix: preserve fast control replies and explicit download choice
sachk Oct 8, 2026
c11262e
fix: retain faint caption strokes in framebuffer OCR
sachk Oct 8, 2026
6cee736
fix(ci): gate releases on supported full-suite runners
sachk Oct 9, 2026
32c179f
docs(release): state native runtime coverage
sachk Oct 9, 2026
ecab0cd
Merge final release gate repairs into profile UX base
sachk Oct 9, 2026
0eb8687
fix(playback): retain authoritative stopped progress across stale cat…
sachk Oct 9, 2026
bff5b99
fix(playback): keep home and queue state current after local progress
sachk Oct 9, 2026
b9d5c42
fix(ui): expose derived resume action on hydrated media items
sachk Oct 9, 2026
5f27071
test(gui): recognize mixed-polarity labels from actual framebuffer pi…
sachk Oct 9, 2026
eee5c77
test(catalog): use canonical library cache keys in progress regression
sachk Oct 9, 2026
ab2bb68
feat(ux): add contextual settings provider homes and native file drops
sachk Oct 9, 2026
c592c98
Merge current playback progress repairs into profile UX
sachk Oct 9, 2026
d041c2b
fix(nix): preserve native test tools across runner shell entry
sachk Oct 9, 2026
cdff3e5
fix(nix): keep native build and launch shells startup-free
sachk Oct 9, 2026
9f9a488
feat(providers): bundle verified Jellyfin and Emby user settings
sachk Oct 9, 2026
33bdd64
Merge native runner fixes and current progress docs
sachk Oct 9, 2026
8aed1f9
Merge settings provider and local media UX into integration branch
sachk Oct 9, 2026
b2fab67
test(network): report benchmark nonce failures without private reques…
sachk Oct 9, 2026
7b3132d
test(state): migrate stop consumers to explicit report operations
sachk Oct 9, 2026
17cc924
fix(runtime): reconcile home lifecycle settled stops and routed journeys
sachk Oct 9, 2026
b3b5a61
test(gui): admit real player scenes and adaptive framebuffer text
sachk Oct 9, 2026
4ee4a3f
test(journey): navigate real settings categories before actions
sachk Oct 9, 2026
4bd1d9f
fix(settings): restore search results and keep journey identities stable
sachk Oct 9, 2026
5dbaabd
fix(tests): provide real prefetch ownership and portable fixture roots
sachk Oct 9, 2026
afd3303
ci: require Linux runtime proof without hosted platform gates
sachk Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Bug report
description: Report a reproducible Spool for Jellyfin defect
description: Report a reproducible Spool defect
title: "[Bug]: "
labels: [bug]
body:
Expand Down
285 changes: 225 additions & 60 deletions .github/workflows/build-artifacts.yml

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- name: Upload corresponding source
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.0
with:
name: spool-for-jellyfin-corresponding-source
name: spool-corresponding-source
path: release-source/*
retention-days: 1

Expand Down Expand Up @@ -137,6 +137,7 @@ jobs:
}
add_row 'macOS — Apple Silicon' '*-macOS-arm64.dmg'
add_row 'macOS — Intel' '*-macOS-x86_64.dmg'
add_row 'Apple TV — unsigned (re-sign required)' '*-tvOS-arm64.ipa'
add_row 'Windows — installer' '*-Windows-x64-Setup.exe'
add_row 'Windows — portable' '*-Windows-x64-Portable.exe'
add_row 'Linux — AppImage' '*-x86_64.AppImage'
Expand Down Expand Up @@ -167,6 +168,11 @@ jobs:
if [[ "$MACOS_SIGNED" != true ]]; then
echo 'The macOS DMG is **not Developer ID signed or notarized**.'
fi
echo
echo 'Release CI requires the complete Linux traditional and real OpenGL/Vulkan GUI suites, Windows OpenGL tests, and the Android phone journey. Full macOS, tvOS simulator, and Android TV native suites remain available manually but do not gate this release; their platform builds and package audits are retained.'
echo
echo 'The Apple TV IPA is **unsigned**: it has no Apple signing identity or provisioning profile, and tvOS will not install it as downloaded. It is not distributed through the App Store or TestFlight and has not been reviewed by Apple.'
echo "Build and sign from source with your own Apple Account, or use your own tvOS re-signing setup. See [Apple TV build and signing directions](https://github.com/$REPO/tree/$TAG#apple-tv)."
} >release-notes.md
- name: Publish GitHub prerelease
env:
Expand Down Expand Up @@ -280,7 +286,7 @@ jobs:
fi
gh release download "$TAG" --repo "$GITHUB_REPOSITORY" \
--pattern SHA256SUMS.txt --dir "$RUNNER_TEMP"
bundle="Spool-for-Jellyfin-$version-linux-x86_64.tar.zst"
bundle="Spool-$version-linux-x86_64.tar.zst"
checksum="$(awk -v want="$bundle" \
'{ sub(/^\*/, "", $2); if ($2 == want) print $1 }' \
"$RUNNER_TEMP/SHA256SUMS.txt")"
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/rescan-release-sboms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ jobs:
mkdir sboms
tag="$(gh release list --exclude-drafts --limit 1 --json tagName --jq '.[0].tagName')"
test -n "$tag"
gh release download "$tag" --pattern '*.cdx.json' --dir sboms
test -n "$(find sboms -type f -name '*.cdx.json' -print -quit)"
gh release download "$tag" --pattern '*.syft.json' --pattern 'ffmpeg-vex.json' --dir sboms
test -n "$(find sboms -type f -name '*.syft.json' -print -quit)"
- name: Enforce vulnerability policy
run: |
set -euo pipefail
for sbom in sboms/*.cdx.json; do
"$RUNNER_TEMP/release-tools/grype" "sbom:$sbom" --fail-on high --only-fixed
for sbom in sboms/*.syft.json; do
"$RUNNER_TEMP/release-tools/grype" "sbom:$sbom" --vex sboms/ffmpeg-vex.json --fail-on high --only-fixed
done
69 changes: 69 additions & 0 deletions .github/workflows/tvos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: tvOS source build

on:
workflow_dispatch:
push:
branches: [feature/tvos]

permissions:
contents: read

concurrency:
group: tvos-${{ github.ref }}
cancel-in-progress: true

jobs:
simulator:
name: Qt mpv tvOS ${{ matrix.sdk }} build (simulator tests; device artifact audit only)
runs-on: macos-15
timeout-minutes: 180
strategy:
fail-fast: false
matrix:
sdk: [appletvsimulator, appletvos]
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
submodules: recursive
persist-credentials: false
- name: Install native build tools
run: brew install cmake ninja meson pkg-config bash python imagemagick gpatch
- name: Install pinned macOS Qt host tools
run: |
python3 -m venv "$RUNNER_TEMP/aqt"
"$RUNNER_TEMP/aqt/bin/pip" install aqtinstall
version="$(python3 -c 'import json;print(json.load(open("tools/manifests/toolchain.json"))["qt"]["version"])')"
"$RUNNER_TEMP/aqt/bin/aqt" install-qt mac desktop "$version" clang_64 \
-O "$RUNNER_TEMP/Qt" -m qtshadertools qtwebsockets qtimageformats qttasktree
echo "QT_HOST_PATH=$RUNNER_TEMP/Qt/$version/macos" >> "$GITHUB_ENV"
- name: Build Qt and media libraries for Apple TV
env:
APPLE_SDK: ${{ matrix.sdk }}
APPLE_ARCH: arm64
JOBS: 3
BUILD_JOBS: 3
run: bash tools/build-tvos.sh
- uses: ./.github/actions/install-nix
if: matrix.sdk == 'appletvsimulator'
with:
nix_conf: |
experimental-features = nix-command flakes
- uses: cachix/cachix-action@3ba601ff5bbb07c7220846facfa2cd81eeee15a1
if: matrix.sdk == 'appletvsimulator'
with:
name: spool
skipPush: true
- name: Build same-binary host controller for the actual mobile app journey
if: matrix.sdk == 'appletvsimulator'
run: nix develop .#native -c env DEPLOY_APP=0 bash tools/build-macos.sh
- name: Run traditional then real GPU GUI tests in isolated Apple TV simulator
if: matrix.sdk == 'appletvsimulator'
run: bash tools/apple/smoke-tvos.sh build/tvos/appletvsimulator-arm64/install/Spool.app
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
if: always()
with:
name: internal-tvos-${{ matrix.sdk }}-arm64
path: |
build/tvos/${{ matrix.sdk }}-arm64/install
build/tvos/smoke/*.png
build/tvos/smoke/*.json
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/build/
/build-linux-dev/
/test-artifacts/
/build-arm/
/app/bin/
/app/lib/
Expand Down
4 changes: 2 additions & 2 deletions .qmlls.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[General]
; QML files live at qml/ and qml/*/, so include both relative depths.
buildDir=../build/linux-dev/app:../../build/linux-dev/app
; QML files live at qml/, qml/*/ and qml/providers/*/, so include every relative depth.
buildDir=../build/linux-dev/app:../../build/linux-dev/app:../../../build/linux-dev/app
no-cmake-calls=true
67 changes: 53 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Project

- Spool for Jellyfin client for webOS and desktop.
- Spool: a media player for webOS, desktop and Android.
- Prefer a smaller, faster, easier-to-extend codebase over compatibility scaffolding or speculative abstractions.
- The app is prerelease software: bump/reset caches on schema changes instead of adding migrations or fallback readers.
- `mpv/` is a submodule. Commit mpv changes inside `mpv/`, then commit its pointer here.
Expand All @@ -29,18 +29,33 @@

## Module Seam

The goal is one core that several backends can sit on (spool-jellyfin,
spool-plex, spool-stremio). `CMakeLists.txt` groups sources into
`SPOOL_PLATFORM_SOURCES`, `SPOOL_PLAYER_SOURCES`, `SPOOL_SHELL_SOURCES` and
`SPOOL_JELLYFIN_SOURCES` to mark where that cut goes. They still build as one
library; the grouping exists so the split stays mechanical.
The app knows no media backend. Every source is a provider package (JS logic
and QML screens) run by `src/provider/`; `docs/providers.md` describes the
pieces and `sdk/` is the current format-3 provider contract. Jellyfin, Emby, Plex and
Stremio live in their `spool-player/spool-*` repositories; Open Movies lives in
`spool-player/spool-provider-example`. All five are bundled from digest-pinned
archives in `providers/lock.json`. Providers and host cut over together; do not add
compatibility shims for older provider/host builds.

- Do not add a `src/api/` or `src/discovery/` include to the platform, player
or shell groups. Four such dependencies already exist and are the work a
split has to undo first: `PlayerController`, `PlaybackReporter`,
`PlayQueueController` and `SettingsController` each take a
`JellyfinApiFacade`, and `configurePlatformPlaybackCapabilities()` is
handed one.
- Core is everything under `src/` except `src/providers/` (native providers;
only `LocalProvider` today) and `src/main.cpp`, the composition root. Core
never includes `src/providers/`; `tools/check-module-seam.sh` is the
`module-seam` ctest.
- The app sees one `Provider`, `SourceHub`, which routes to every enabled
account. IDs leaving it are scoped (`<8 hex>:<id>`) and stay opaque to
routes, caches and QML. Pages reach media through `Catalog`,
`SearchSource`, `UserItemStateSink`, `ArtworkSource`, `PlaybackSource` and
`StreamQualityControl`, never a provider type.
- Shared QML gates optional controls on the `ProviderCapabilities` singleton
(search, userItemState, playbackReporting, segments, groupPlayback,
remoteControl, streamQuality, trickplay): what the enabled accounts can do
between them. Provider-specific UI is the provider's own QML, mounted by
`shell/ProviderSurface` with a `ProviderUiContext`; item-menu entries come
from the manifest's `actions`.
- Group playback and remote control are generic (`GroupPlaybackController`,
`AppControllerRemote.cpp`); providers translate their protocol into
`group` and `remote` events. Do not touch `src/player` or
`qml/pages/Player*` for provider work beyond renames.
- `qml/primitives` and `qml/theme` reach exactly two singletons, `Art.url` and
`Settings.uiScalePercent`. Keep it that way; page- and shell-level QML is
where backend-shaped data belongs.
Expand All @@ -52,6 +67,12 @@ library; the grouping exists so the split stays mechanical.
- `tools/manifests/toolchain.json` sets the Qt and FFmpeg versions for every
platform. Nothing else may name one; `tools/toolchain-versions.sh --check`
is what CI runs to keep the Qt module manifests honest.
- Qt source manifests use the official-listed FAU archive mirror rather than a
geo-selected redirect. Mirror changes must preserve version/module SHA-256 pins;
verify the full archive digest before changing a source URL.
- webOS GCC coroutine calls use named argument maps before `co_await`; nesting
a member expression inside a temporary argument aggregate triggered a compiler
internal error. Keep the wire arguments unchanged when restructuring such calls.
- The launch screen carries the version, so it is rendered per build by
`tools/generate-splash.sh` from `tools/manifests/splash.json` and is not
committed. Configuring the app is enough to get it on every platform.
Expand All @@ -61,12 +82,30 @@ library; the grouping exists so the split stays mechanical.
- Launch the native release app with `nix run`. Clean Git revisions substitute the immutable package from Cachix; dirty tracked changes use the incremental checkout build.
- Launch the already-built native release app without rebuilding with `nix run .#run`. It fails with a build-command hint when the binary is missing.
- Build without launching with `nix run .#build`.
- Run the test suite the way CI does with `nix run .#tests` (release build, then the same ctest invocation and exclusions as the workflow).
- Run the test suite the way CI does with `nix run .#tests` (release build, then `python tools/run-tests.py --build-dir <dir> --workers N`: traditional selectors finish before real GUI e2e; failures aggregate without GPU exclusions).
- Leave interactive UI testing to the user. Do not drive their desktop with xdotool/xdgtool or similar input automation, or launch visible smoke tests unless explicitly requested. Use builds and isolated/offscreen checks for verification.
- Use `nix develop .#native -c ...` for targeted development commands (e.g. `cmake --preset linux-dev`, then `cmake --build build/linux-dev/app --target jellyfin-native`).
- Use `nix develop .#native -c ...` for targeted development commands (e.g. `cmake --preset linux-dev`, then `cmake --build build/linux-dev/app --target spool`).
- The image-diagnostics equivalents remain `nix run .#image-debug-build` followed by `nix run .#image-debug`.
- Batch coherent edits, then run one build and one `qmlformat`/`clang-format` invocation over all touched files; don't build or format file-by-file.

### Filtered preview diagnostics

- Trace is opt-in: `QT_LOGGING_RULES='spool.provider.trace.debug=true'`.
Enable it only for the shortest necessary inspection, then unset it.
- Never print or share unfiltered app logs, diagnostics JSON, provider responses,
credential stores, URLs, request headers, or account configuration. Restoration
must use the real app's existing credential path, never pasted tokens.
- Always filter trace output before displaying it: select only `preview metadata`,
`preview session`, `preview fetch failed`, and `preview load failed` messages
from `spool.provider.trace`. Prefer an explicit field allowlist (item ID,
enabled, availability, format, dimensions/count, numeric network/status codes,
frame/speculative). Redact authentication, URL/query, user/account and path
values even if upstream logging is already sanitized.
- `spoolet` may inspect restored-account library rows and drive an explicitly
requested offscreen preview smoke. Filter JSON to the required titles, IDs,
player/preview state and dimensions. Never dump raw provider payloads or
support reports to discover preview availability.

## webOS

- Do not build, install, launch, deploy, or test on a TV unless the user explicitly requests it. "Deploy" means install-only; never launch unless separately asked.
Expand Down
Loading
Loading