name: linthra
description: A modern, local-first, privacy-focused music player.
publish_to: "none"
# Single source of truth for the release version: <versionName>+<versionCode>.
# Bumped to match each release tag (see docs/release-process.md §1 & §3). The
# versionCode is the canonical encoding of the versionName from
# tool/version_from_tag.dart (0.1.0-alpha.36 -> 100036);
# test/core/app_info_version_test.dart enforces that. Flutter reads both into the
# Android build (versionName/versionCode) and the in-app version mirrors it via
# AppInfo._devVersionName, so a plain `flutter build` (CI and F-Droid alike) and
# the tag all agree.
version: 0.1.15+115999

environment:
  sdk: ">=3.6.0 <4.0.0"

# Dependencies are added as features need them, not speculatively.
# The planned full stack (just_audio, audio_service, drift, connectivity_plus,
# permission_handler, ...) is documented in README.md and wired in behind the
# interfaces under lib/services and lib/storage when each feature lands.
dependencies:
  flutter:
    sdk: flutter
  flutter_riverpod: ^2.6.1
  go_router: ^14.6.2
  # Cross-platform path parsing for the local file scanner (Dart-team package).
  path: ^1.9.0
  # SQLite-backed local catalog persistence (the offline-first cache the UI
  # reads from). drift is the typed query layer; sqlite3_flutter_libs bundles
  # the native SQLite engine on device; path_provider locates the on-device
  # database file.
  drift: ^2.18.0
  sqlite3_flutter_libs: ^0.5.20
  path_provider: ^2.1.4
  # Local audio playback engine. Used only by JustAudioPlaybackController in the
  # services layer; the UI depends on the PlaybackController interface, never on
  # just_audio directly.
  just_audio: ^0.9.42
  # Background playback + platform media session (notification, lock screen,
  # Android Auto). Used only by LinthraAudioHandler in the services layer, which
  # forwards session commands to PlaybackController and mirrors its state out.
  # The UI never depends on audio_service directly.
  audio_service: ^0.18.15
  # Audio-focus / interruption handling for the on-device engine. just_audio's
  # built-in handler auto-resumes playback on focus regain (the screen-wake /
  # app-switch "music starts by itself" bug), so JustAudioPlaybackController
  # disables it and owns focus deliberately through this seam: it pauses on a
  # real focus loss and never auto-resumes. Already a transitive dependency of
  # just_audio/audio_service; declared here because the services layer imports
  # it directly. The UI never depends on audio_session.
  audio_session: ^0.1.25
  # Native folder chooser for selecting a music folder to scan. Used only by
  # FilePickerFolderPickerService; the UI depends on the FolderPickerService
  # interface, never on file_picker directly.
  file_picker: ^8.1.4
  # Persists the single selected music folder path/URI across restarts. Used
  # only by SharedPreferencesSelectedMusicFolderRepository, behind the
  # SelectedMusicFolderRepository interface.
  shared_preferences: ^2.3.3
  # HTTP client for talking to a Jellyfin server (including HTTPS Cloudflare-
  # proxied domains). Used only by HttpJellyfinClient in the Jellyfin source;
  # the rest of the app depends on the JellyfinClient interface, never on http
  # directly. The Dart-team package, so it stays small and dependency-light.
  http: ^1.2.0
  # MD5 hashing for the Subsonic/Navidrome token+salt auth scheme
  # (token = md5(password + salt)). Used only by SubsonicAuth so a Subsonic
  # session can authenticate every request without ever persisting the
  # plaintext password — only the derived (salt, token) is stored, encrypted.
  # A Dart-team package (BSD-3, MIT-compatible), small and dependency-light.
  crypto: ^3.0.3
  # Runtime permission requests. Used only by
  # PermissionHandlerNotificationPermission to ask for POST_NOTIFICATIONS on
  # Android 13+ so the audio_service media notification can appear; the rest of
  # the app depends on the NotificationPermission interface, never on
  # permission_handler directly.
  permission_handler: ^11.3.1
  # Encrypted on-device storage for the Jellyfin session token (Android
  # Keystore / EncryptedSharedPreferences under the hood). Used only by
  # SecureJellyfinSessionStore, behind the JellyfinSessionStore interface, so
  # the token never lands in plaintext and tests stay plugin-free on the
  # in-memory default. Passwords are never persisted at all.
  flutter_secure_storage: ^9.2.2
  # Real Chromecast support, used ONLY by ChromecastCastTransport behind the
  # CastTransport/CastService interfaces; the UI and the rest of the app never
  # touch it directly. This is a pure-Dart implementation of the Google Cast v2
  # protocol (mDNS discovery via `bonsoir`, a TLS socket, protobuf framing) — it
  # does NOT use the proprietary Google Cast SDK or Google Play Services, so it
  # stays F-Droid/open-source compatible (MIT). `bonsoir` is pinned to 5.x for
  # Dart 3.6 compatibility (6.x+ needs Dart >=3.8). See
  # docs/dependency-license-audit.md §"Cast" and docs/fdroid-readiness.md.
  cast: ^2.1.0
  bonsoir: ^5.1.11
  # Opens an external URL (the user's browser) for the "Report a bug" flow's
  # "Open GitHub issue" action, which hands the browser a prefilled — but
  # unsubmitted — issue the user reviews and submits themselves. Used ONLY by
  # UrlLauncherExternalLinkLauncher behind the ExternalLinkLauncher interface;
  # the UI never calls url_launcher directly. The official Flutter-team plugin
  # (BSD-3-Clause); on Android it fires a standard AOSP VIEW intent — no Google
  # Play Services. The app never auto-opens anything; every launch is an
  # explicit user tap. See docs/dependency-license-audit.md §"Reporting a bug".
  url_launcher: ^6.3.0

dev_dependencies:
  flutter_lints: ^5.0.0
  flutter_test:
    sdk: flutter
  # Drift code generation. Run via the manual "Generate Drift files" workflow;
  # produces the *.g.dart files that back LinthraDatabase.
  drift_dev: ^2.18.0
  build_runner: ^2.4.13

flutter:
  uses-material-design: true
