diff --git a/.gitignore b/.gitignore index 8560f45..433fe99 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,11 @@ yarn-debug.log* yarn-error.log* pnpm-debug.log* +# Use bun (see packageManager in package.json); ignore other package managers' lockfiles +package-lock.json +yarn.lock +pnpm-lock.yaml + # Build output /build /dist diff --git a/README.md b/README.md index d552854..1bcfc06 100644 --- a/README.md +++ b/README.md @@ -2,335 +2,25 @@ A cross-platform Jellyfin client built with Tauri, SvelteKit, and TypeScript. -## Recommended IDE Setup +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). -[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer). +## Getting Started ---- - -# Requirements Specification - -## 1. User Requirements - -| ID | Requirement | Priority | Status | -|----|-------------|----------|--------| -| UR-001 | Run the app on multiple platforms (Linux, Android) | High | In Progress | -| UR-002 | Access media when online or offline | High | Done | -| UR-003 | Play videos | High | Done | -| UR-004 | Play audio uninterrupted | High | Done | -| UR-005 | Control media playback (pause, play, skip, scrub) | High | Done | -| UR-006 | Control media when device is on lock screen or via BLE headsets | Medium | Done | -| UR-007 | Navigate media in library | High | Done | -| UR-008 | Search media across libraries | High | Done | -| UR-009 | Connect to Jellyfin to access media | High | Done | -| UR-010 | Control playback of Jellyfin remote sessions | Low | Done | -| UR-011 | Download media on demand | Medium | Done | -| UR-012 | Login info shall be stored securely and persistently | High | Done | -| UR-013 | View and manage downloaded media | Medium | Done | -| UR-014 | Make and edit playlists of music that sync back to Jellyfin | Medium | Done | -| UR-015 | View and manage current audio queue (add, reorder tracks) | Medium | Done | -| UR-016 | Change system settings while playing (brightness, volume) | Low | Planned | -| UR-017 | Like or unlike audio, albums, movies, etc. | Medium | Done | -| UR-018 | Choose to download series, albums, songs, artist discography | Medium | Done | -| UR-019 | Resume playback from where you left off (movies, shows, albums) | High | Done | -| UR-020 | Select subtitles for video content | High | Done | -| UR-021 | Select audio track for video content | High | Done | -| UR-022 | Control streaming quality and transcoding settings | Medium | Planned | -| UR-023 | View "Next Up" / Continue Watching on home screen; auto-play next episode with countdown popup and configurable episode limit | Medium | Done | -| UR-024 | View recently added content on server | Medium | Done | -| UR-025 | Sync watch history and progress back to Jellyfin | High | Done | -| UR-026 | Sleep timer for audio and video playback (roller UI, time/track/episode modes) | Low | Done | -| UR-027 | Audio equalizer for sound customization | Low | Planned | -| UR-028 | Navigate to artist/album by tapping names in now playing view | High | Done | -| UR-029 | Toggle between grid and list view in library | Medium | Done | -| UR-030 | Quick genre browsing and filtering | Medium | Done | -| UR-031 | Crossfade between audio tracks | Low | Done (Linux only) | -| UR-032 | Gapless playback for seamless album listening | Medium | Done (Linux only) | -| UR-033 | Volume normalization to prevent volume jumps between tracks | Low | Done (Linux only) | -| UR-034 | Rich home screen with hero banners, carousels, and personalized sections | High | Done | -| UR-035 | View cast/crew (actors, directors) on movie/show detail pages | High | Done | -| UR-036 | Navigate to actor/person page showing their filmography | Medium | Done | -| UR-037 | Visually appealing video library with poster grids and metadata | High | Done | -| UR-038 | Movie/show detail page with backdrop, ratings, and rich metadata | High | Done | -| UR-039 | Navigate between main sections via bottom navigation bar | High | Done | - ---- - -## 2. Software Requirements - -### 2.1 Integration Requirements - -External system integrations and platform-specific implementations. - -| ID | Requirement | Category | Traces To | Status | -|----|-------------|----------|-----------|--------| -| IR-001 | Build system supporting multiple targets (Linux, Android) | Build | UR-001 | Done | -| IR-002 | Build scripts for Android and Linux | Build | UR-001 | Done | -| IR-003 | Integration of libmpv for Linux playback | Playback | UR-003, UR-004 | Done | -| IR-004 | Integration of ExoPlayer for Android playback | Playback | UR-003, UR-004 | In Progress (basic playback works, audio settings missing) | -| IR-005 | MPRIS D-Bus integration for Linux lockscreen/media controls | Platform | UR-006 | Planned | -| IR-006 | Android MediaSession integration for lockscreen controls | Platform | UR-006 | Done | -| IR-007 | Bluetooth AVRCP integration via system media session | Platform | UR-006 | Planned | -| IR-008 | Android audio focus handling (pause on call) | Platform | UR-004, UR-006 | Done | -| IR-009 | Jellyfin API client for authentication | API | UR-009, UR-012 | Done | -| IR-010 | Jellyfin API client for library browsing | API | UR-007, UR-008 | Done | -| IR-011 | Jellyfin API client for playback streaming | API | UR-003, UR-004 | Done | -| IR-012 | Jellyfin Sessions API for remote playback control | API | UR-010 | Done | -| IR-021 | Android MediaRouter integration for remote volume in system panel | Platform | UR-010, UR-016 | Planned | -| IR-013 | SQLite integration for local database | Storage | UR-002, UR-011 | Done | -| IR-014 | Secure credential storage (keyring/keychain) | Security | UR-012 | Done | -| IR-015 | Jellyfin API client for playback progress reporting | API | UR-019, UR-025 | Done | -| IR-016 | Jellyfin API client for subtitle/audio track info | API | UR-020, UR-021 | Done | -| IR-017 | Jellyfin API client for transcoding parameters | API | UR-022 | Planned | -| IR-018 | libmpv subtitle rendering and selection | Playback | UR-020 | Planned | -| IR-019 | libmpv audio track selection | Playback | UR-021 | Planned | -| IR-020 | libmpv/ExoPlayer equalizer integration | Playback | UR-027 | Planned | -| IR-022 | Jellyfin API client for person/cast data | API | UR-035, UR-036 | Done | -| IR-023 | Database schema for person/cast caching | Storage | UR-035, UR-036 | Done | -| IR-024 | Jellyfin API client for home screen data (featured, continue watching) | API | UR-034 | Done | - -### 2.2 Jellyfin API Requirements - -API endpoints and data contracts required for Jellyfin integration. - -| ID | Requirement | Endpoint Category | Traces To | Status | -|----|-------------|-------------------|-----------|--------| -| JA-001 | Server connection and discovery | System | UR-009 | Done | -| JA-002 | User authentication (username/password) | Users | UR-009, UR-012 | Done | -| JA-003 | Get user library views | UserViews | UR-007 | Done | -| JA-004 | Get library items (paginated) | Items | UR-007 | Done | -| JA-005 | Get item details and metadata | Items | UR-007 | Done | -| JA-006 | Search across libraries | Items | UR-008 | Done | -| JA-007 | Get playback info and stream URL | MediaInfo | UR-003, UR-004 | Done | -| JA-008 | Get available subtitles for item | MediaInfo | UR-020 | Done | -| JA-009 | Get available audio tracks for item | MediaInfo | UR-021 | Done | -| JA-010 | Report playback start | Sessions | UR-025 | Done | -| JA-011 | Report playback progress (periodic) | Sessions | UR-025 | Done | -| JA-012 | Report playback stopped | Sessions | UR-025 | Done | -| JA-013 | Get resume position for item | UserData | UR-019 | Done | -| JA-014 | Get "Next Up" items | Shows | UR-023 | Done | -| JA-015 | Get "Continue Watching" items | Items | UR-023 | Done | -| JA-016 | Get recently added items | Items | UR-024 | Done | -| JA-017 | Mark item as favorite | UserData | UR-017 | Done | -| JA-018 | Remove item from favorites | UserData | UR-017 | Done | -| JA-019 | Get/create/update playlists | Playlists | UR-014 | Done | -| JA-020 | Add/remove items from playlist | Playlists | UR-014 | Done | -| JA-021 | Get active sessions list | Sessions | UR-010 | Done | -| JA-022 | Send playback commands to remote session (play/pause/stop) | Sessions | UR-010 | Done | -| JA-023 | Send seek command to remote session | Sessions | UR-010 | Done | -| JA-024 | Send next/previous track commands to remote session | Sessions | UR-010 | Done | -| JA-025 | Play specific item on remote session | Sessions | UR-010 | Done | -| JA-026 | Send volume/mute commands to remote session | Sessions | UR-010 | Done | -| JA-027 | Get transcoding options | MediaInfo | UR-022 | Planned | -| JA-028 | Get image/artwork URLs | Images | UR-007 | Done | -| JA-029 | Get cast/crew for item (actors, directors) | Items | UR-035 | Done | -| JA-030 | Get person details and filmography | Persons | UR-036 | Done | -| JA-031 | Get items by person (actor/director filmography) | Items | UR-036 | Done | - -### 2.3 Development Requirements - -Internal architecture, components, and application logic. - -| ID | Requirement | Category | Traces To | Status | -|----|-------------|----------|-----------|--------| -| DR-001 | Player state machine (idle, loading, playing, paused, seeking, error) | Player | UR-005 | Done | -| DR-002 | MediaItem struct tracking source, location, duration, metadata | Player | UR-003, UR-004 | Done | -| DR-003 | Source-agnostic media abstraction (Remote, Local, DirectUrl) | Player | UR-002, UR-011 | Done | -| DR-004 | PlayerBackend trait for platform-agnostic playback | Player | UR-003, UR-004 | Done | -| DR-005 | Queue manager with shuffle, repeat, history | Player | UR-005, UR-015 | Done | -| DR-006 | Audio pre-caching for seamless track transitions | Player | UR-004 | Planned | -| DR-007 | Library browsing screens (grid view, search, filters) | UI | UR-007, UR-008 | Done | -| DR-008 | Album/Series detail view with track listing | UI | UR-007 | Done | -| DR-009 | Audio player UI (mini player, full screen) | UI | UR-005 | Done | -| DR-010 | Video player UI (fullscreen, controls overlay) | UI | UR-003, UR-005 | Done | -| DR-011 | Search bar with cross-library search | UI | UR-008 | Done | -| DR-012 | Local database for media metadata cache | Storage | UR-002 | Done | -| DR-013 | Repository pattern for online/offline data access | Storage | UR-002 | Done | -| DR-014 | Offline mutation queue for sync-back operations | Storage | UR-002, UR-014, UR-017 | Done | -| DR-015 | Download manager with queue and progress tracking | Storage | UR-011, UR-018 | Done | -| DR-016 | Thumbnail caching and sync with server | Storage | UR-007 | Done | -| DR-017 | "Manage Downloads" screen for local media management | UI | UR-013 | Done | -| DR-018 | Download buttons on library/album/player screens | UI | UR-011, UR-018 | Done | -| DR-019 | Playlist creation and editing UI | UI | UR-014 | Done | -| DR-020 | Queue management UI (add, remove, reorder) | UI | UR-015 | Done | -| DR-021 | Like/favorite functionality on media items | UI | UR-017 | Done | -| DR-022 | Resume position tracking and restoration on play | Player | UR-019 | Done | -| DR-023 | Subtitle selection UI in video player | UI | UR-020 | Done | -| DR-024 | Audio track selection UI in video player | UI | UR-021 | Done | -| DR-025 | Quality/transcoding settings UI | UI | UR-022 | Planned | -| DR-026 | "Continue Watching" / "Next Up" home section | UI | UR-023 | Done | -| DR-027 | "Recently Added" home section | UI | UR-024 | Done | -| DR-028 | Playback progress sync service (periodic reporting) | Player | UR-025 | Done | -| DR-029 | Sleep timer with roller UI, time/track/episode modes, and auto-stop (audio + video players) | Player | UR-026 | Done | -| DR-049 | Auto-play episode limit (configurable max episodes per session) | Player | UR-023 | Done | -| DR-050 | Reusable scroll picker (roller) component | UI | UR-026 | Done | -| DR-030 | Equalizer UI with presets and custom bands | UI | UR-027 | Planned | -| DR-031 | Clickable artist/album links in now playing view | UI | UR-028 | Done | -| DR-032 | List view option for library browsing (albums, artists) | UI | UR-029 | Done | -| DR-033 | Genre browsing screen with quick filters | UI | UR-030 | Done | -| DR-034 | Crossfade engine with configurable duration (0-12s) | Player | UR-031 | Done (Linux only) | -| DR-035 | Gapless playback between sequential tracks | Player | UR-032 | Done (Linux only) | -| DR-036 | Volume normalization with preset levels (Loud/Normal/Quiet) | Player | UR-033 | Done (Linux only) | -| DR-037 | Remote session browser and control UI | UI | UR-010 | Done | -| DR-038 | Home screen with hero banner carousel (featured/continue watching) | UI | UR-034 | Done | -| DR-039 | Home screen horizontal carousels (recently added, recommendations) | UI | UR-034, UR-024 | Done | -| DR-040 | Cast/crew section on movie/show detail pages | UI | UR-035 | Done | -| DR-041 | Person/actor detail page with filmography grid | UI | UR-036 | Done | -| DR-042 | Video library grid with poster cards, year, and rating badges | UI | UR-037 | Done | -| DR-043 | Movie/show detail page with backdrop hero, synopsis, and metadata | UI | UR-038 | Done | -| DR-044 | Horizontal scrolling actor/cast row with profile images | UI | UR-035 | Done | -| DR-045 | Bottom navigation bar with Home, Library, Search buttons | UI | UR-039 | Done | -| DR-046 | Dedicated search page with input and results | UI | UR-039 | Done | -| DR-047 | Next episode auto-play popup with configurable countdown and episode limit | Player | UR-023 | Done | -| DR-048 | Video settings (auto-play toggle, countdown duration, episode limit) | Settings | UR-023, UR-026 | Done | - ---- - -## 3. Traceability Matrix - -### User Requirements to Software Requirements - -| User Req | Integration Requirements | Development Requirements | -|----------|-------------------------|-------------------------| -| UR-001 | IR-001, IR-002 | - | -| UR-002 | IR-013 | DR-003, DR-012, DR-013, DR-014 | -| UR-003 | IR-003, IR-004, IR-011 | DR-002, DR-004, DR-010 | -| UR-004 | IR-003, IR-004, IR-008, IR-011 | DR-002, DR-004, DR-006 | -| UR-005 | - | DR-001, DR-005, DR-009 | -| UR-006 | IR-005, IR-006, IR-007, IR-008 | - | -| UR-007 | IR-010 | DR-007, DR-008, DR-016 | -| UR-008 | IR-010 | DR-007, DR-011 | -| UR-009 | IR-009, IR-010, IR-011 | - | -| UR-010 | IR-012, IR-021 | DR-037 | -| UR-011 | IR-013 | DR-003, DR-015, DR-018 | -| UR-012 | IR-009, IR-014 | - | -| UR-013 | IR-013 | DR-017 | -| UR-014 | IR-010 | DR-014, DR-019 | -| UR-015 | - | DR-005, DR-020 | -| UR-016 | - | - | -| UR-017 | - | DR-014, DR-021 | -| UR-018 | IR-013 | DR-015, DR-018 | -| UR-019 | IR-015 | DR-022 | -| UR-020 | IR-016, IR-018 | DR-023 | -| UR-021 | IR-016, IR-019 | DR-024 | -| UR-022 | IR-017 | DR-025 | -| UR-023 | IR-010 | DR-026, DR-047, DR-048, DR-049 | -| UR-024 | IR-010 | DR-027 | -| UR-025 | IR-015 | DR-028 | -| UR-026 | - | DR-029, DR-048, DR-050 | -| UR-027 | IR-020 | DR-030 | -| UR-028 | - | DR-031 | -| UR-029 | - | DR-032 | -| UR-030 | IR-010 | DR-033 | -| UR-031 | - | DR-034 | -| UR-032 | - | DR-035 | -| UR-033 | - | DR-036 | -| UR-034 | IR-010, IR-024 | DR-038, DR-039 | -| UR-035 | IR-022, IR-023 | DR-040, DR-044 | -| UR-036 | IR-022, IR-023 | DR-041 | -| UR-037 | IR-010 | DR-042 | -| UR-038 | IR-010 | DR-043 | -| UR-039 | - | DR-045, DR-046 | - ---- - -## 4. Test Traceability - -### Unit Tests to Software Requirements - -| Test ID | Test Description | Traces To | Status | -|---------|-----------------|-----------|--------| -| UT-001 | Player state transitions | DR-001 | Pending | -| UT-002 | MediaItem source URL resolution | DR-002, DR-003 | Pending | -| UT-003 | Queue next/previous navigation | DR-005 | Pending | -| UT-004 | Queue shuffle order generation | DR-005 | Pending | -| UT-005 | Queue repeat mode behavior | DR-005 | Pending | -| UT-006 | Jellyfin authentication flow | IR-009 | Pending | -| UT-007 | Jellyfin library items parsing | IR-010 | Pending | -| UT-008 | Repository pattern online/offline switching | DR-013 | Pending | -| UT-009 | Offline mutation queue persistence | DR-014 | Pending | -| UT-010 | Download queue management | DR-015 | Done | -| UT-011 | Resume position storage and retrieval | DR-022 | Pending | -| UT-012 | Sleep timer countdown logic | DR-029 | Pending | -| UT-013 | Playback progress reporting throttling | DR-028 | Pending | -| UT-014 | Database open and in-memory mode | IR-013, DR-012 | Done | -| UT-015 | Database migrations run successfully | IR-013, DR-012 | Done | -| UT-016 | All database tables created | IR-013, DR-012 | Done | -| UT-017 | FTS5 search table created | IR-013, DR-012 | Done | -| UT-018 | Server CRUD operations | IR-013, DR-012 | Done | -| UT-019 | User CRUD operations | IR-013, DR-012 | Done | -| UT-020 | Cascade delete server removes users | IR-013, DR-012 | Done | -| UT-021 | Item insert and FTS search | IR-013, DR-012 | Done | -| UT-022 | User data playback position storage | IR-013, DR-012, DR-022 | Done | -| UT-023 | Sync queue operations | IR-013, DR-014 | Done | -| UT-024 | Downloads table operations | IR-013, DR-015 | Done | -| UT-025 | Migrations are idempotent | IR-013, DR-012 | Done | -| UT-026 | NullBackend volume default value | DR-004 | Done | -| UT-027 | NullBackend set volume | DR-004 | Done | -| UT-028 | NullBackend volume clamping (high/low) | DR-004 | Done | -| UT-029 | NullBackend volume boundary values | DR-004 | Done | -| UT-030 | PlayerController volume default | DR-004, DR-009 | Done | -| UT-031 | PlayerController set volume | DR-004, DR-009 | Done | -| UT-032 | PlayerController muted default | DR-004, DR-009 | Done | -| UT-033 | PlayerController volume delegates to backend | DR-004, DR-009 | Done | -| UT-034 | Download event serialization roundtrip | DR-015 | Done | -| UT-035 | Download event completed serialization | DR-015 | Done | -| UT-036 | Download event failed serialization | DR-015 | Done | -| UT-037 | Download worker exponential backoff | DR-015 | Done | -| UT-038 | Download worker error retryable check | DR-015 | Done | -| UT-039 | Download manager creation | DR-015 | Done | -| UT-040 | Download manager set max concurrent | DR-015 | Done | -| UT-041 | Download info serialization | DR-015 | Done | -| UT-042 | Download command filename sanitization | DR-015, DR-018 | Done | -| UT-043 | Download command filename extension preservation | DR-015, DR-018 | Done | -| UT-044 | Offline item serialization | DR-017 | Done | -| UT-045 | Smart cache default config | DR-015 | Done | -| UT-046 | Smart cache album affinity tracking | DR-015 | Done | -| UT-047 | Smart cache queue precache config | DR-015 | Done | -| UT-048 | Smart cache storage limit check | DR-015 | Done | -| UT-049 | Playlist create (offline) | DR-019, JA-019 | Done | -| UT-050 | Playlist delete (offline) | DR-019, JA-019 | Done | -| UT-051 | Playlist rename (offline) | DR-019, JA-019 | Done | -| UT-052 | Playlist get items (offline) | DR-019, JA-019 | Done | -| UT-053 | Playlist add items (offline) | DR-019, JA-020 | Done | -| UT-054 | Playlist remove items (offline) | DR-019, JA-020 | Done | -| UT-055 | Playlist reorder items (offline) | DR-019, JA-020 | Done | -| UT-056 | Playlist entry serialization | DR-019, JA-019 | Done | -| UT-057 | Playlist Tauri command param naming (camelCase) | DR-019, JA-019, JA-020 | Done | -| UT-058 | Playlist repository client methods | DR-019, JA-019, JA-020 | Done | - -### Integration Tests - -| Test ID | Test Description | Traces To | Status | -|---------|-----------------|-----------|--------| -| IT-001 | End-to-end authentication with Jellyfin server | IR-009, UR-009 | Pending | -| IT-002 | Library browsing and item loading | IR-010, UR-007 | Pending | -| IT-003 | Audio playback via libmpv | IR-003, UR-004 | Pending | -| IT-004 | Video playback via libmpv | IR-003, UR-003 | Pending | -| IT-005 | MPRIS lockscreen controls on Linux | IR-005, UR-006 | Pending | -| IT-006 | Offline mode with local database | IR-013, UR-002 | Pending | -| IT-007 | Media download and local playback | DR-015, UR-011 | Pending | -| IT-008 | Subtitle track selection via libmpv | IR-018, UR-020 | Pending | -| IT-009 | Audio track selection via libmpv | IR-019, UR-021 | Pending | -| IT-010 | Playback progress sync to Jellyfin | IR-015, UR-025 | Pending | -| IT-011 | Resume playback from server position | IR-015, UR-019 | Pending | -| IT-012 | Equalizer bands via libmpv | IR-020, UR-027 | Pending | - ---- - -## 5. Development Commands +This project uses [bun](https://bun.sh) as its package manager. ```bash -# Activate Rust environment (fish shell) +# Activate the Rust environment (fish shell) source "$HOME/.cargo/env.fish" # Install dependencies bun install -# Development +# Run in development bun run tauri dev -# Type checking +# Type-check the frontend bun run check # Build for Linux @@ -340,168 +30,28 @@ bun run tauri build bun run tauri android build ``` ---- +For the full set of build, test, and Android helper scripts, see +[scripts/README.md](scripts/README.md). -## 6. Architecture Overview +## Documentation -``` -jellytau/ -├── src/ # Svelte frontend -│ ├── lib/ -│ │ ├── api/ # Jellyfin API client (repository pattern) -│ │ ├── components/ # UI components (player, library) -│ │ └── stores/ # Svelte stores (auth, library, player, queue) -│ └── routes/ # SvelteKit pages -├── src-tauri/ # Rust backend -│ ├── src/ -│ │ ├── commands/ # Tauri commands -│ │ └── player/ # Player architecture -│ │ ├── state.rs # State machine -│ │ ├── media.rs # MediaItem, MediaSource -│ │ ├── queue.rs # Queue management -│ │ └── backend.rs # PlayerBackend trait -│ └── gen/android/ # Android project -└── README.md -``` +| Topic | Location | +|-------|----------| +| Architecture overview & subsystem docs | [docs/architecture/](docs/architecture/) | +| Requirements, traceability & technical debt | [docs/requirements.md](docs/requirements.md) | +| Build & release process | [docs/build-release.md](docs/build-release.md) | +| Docker builds | [docs/build/docker.md](docs/build/docker.md) | +| Traceability tooling & CI | [docs/traceability.md](docs/traceability.md), [docs/traceability-ci.md](docs/traceability-ci.md) | +| Release checklist | [docs/release-checklist.md](docs/release-checklist.md) | +| UX flows | [docs/ux-flows.md](docs/ux-flows.md) | ---- +## Recommended IDE Setup -## 7. Technical Debt +[VS Code](https://code.visualstudio.com/) + +[Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + +[Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + +[rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer). -### Linux Keyring Integration Workaround +## License -**Issue**: The `keyring-rs` crate (v3.x) has issues with retrieving credentials from the Linux Secret Service API, despite successfully saving them. - -**Symptoms**: -- Credentials are saved to the system keyring successfully (verified with `secret-tool search`) -- Retrieval via the `keyring-rs` library fails with `NoEntry` error -- Session restoration fails on app restart even though credentials exist - -**Root Cause**: -The `keyring-rs` library's Linux backend doesn't correctly retrieve entries from the Secret Service that it previously stored. This appears to be a bug in how the library interfaces with the Secret Service D-Bus API. - -**Current Workaround**: -We bypass the `keyring-rs` library on Linux and use direct system calls to `secret-tool`: -- **Save**: `secret-tool store --label