# AGENTS.md This file is the working guide for people and agents changing MoonWell Launcher. Keep it current when architecture, commands, or repository rules change. ## Project Shape MoonWell Launcher is a Flutter desktop app for a private World of Warcraft: Wrath of the Lich King server. It logs players in, downloads and synchronizes client files, displays launcher news, and starts `Wow.exe`. Important areas: - `lib/main.dart` initializes Flutter, the desktop window, dependency injection, and `MoonWellApp`. - `lib/app` contains UI screens, BLoC state, widgets, and theme code. - `lib/app/widgets` contains shared app-level UI such as the custom desktop title bar. - `lib/app/design_system` contains presentation-only catalog components. - `widgetbook/` is the standalone component-catalog workspace. Stories and fixture data stay in that workspace and import components from the launcher. - `lib/features/launcher/domain` contains launcher entities such as sessions, manifests, news items, sync status, and exceptions. - `lib/features/launcher/application` contains use cases for session restore and client synchronization. - `lib/features/launcher/data` contains API, installation, and log services. - `lib/features/preferences` stores selected install directory and launcher session data. Launcher sessions must use secure storage; non-sensitive preferences may use `shared_preferences`. - `lib/service_container.dart` and `lib/service_container.config.dart` provide `get_it`/`injectable` dependency wiring. - `docs/launcher_web_api_spec.md` documents the current launcher Web API and sync behavior. ## Flutter SDK Policy MoonWell Launcher tracks the latest stable Flutter SDK through FVM. Run all Dart and Flutter commands through `fvm` and keep `.fvmrc` on the stable channel. ## Common Commands ```powershell fvm flutter pub get fvm dart run build_runner build --delete-conflicting-outputs fvm dart format --set-exit-if-changed . fvm flutter analyze fvm flutter test fvm flutter run -d windows --dart-define=MOONWELL_API_BASE_URL=https://host --dart-define=MOONWELL_APPCAST_URL=https://host/launcher/updates/appcast.xml fvm flutter build windows --dart-define=MOONWELL_API_BASE_URL=https://host --dart-define=MOONWELL_APPCAST_URL=https://host/launcher/updates/appcast.xml cd widgetbook fvm flutter pub get fvm dart run build_runner build fvm flutter run -d windows ``` See `docs/linting.md` for the required format, analyze, test, and Lefthook pre-commit workflow. Follow `docs/widgetbook.md` for all Widgetbook use-case generation. ## Configuration The launcher API base URL is compile-time configuration: ```powershell --dart-define=MOONWELL_API_BASE_URL=https://host ``` The optional Windows self-update feed is also compile-time configuration: ```powershell --dart-define=MOONWELL_APPCAST_URL=https://host/launcher/updates/appcast.xml ``` Production AppCast feeds must be public HTTPS URLs. Omit the setting to disable self-update in local builds. Do not commit private credentials, production secrets, temporary bearer tokens, or local-only API URLs. ## Architecture Notes - All backend calls should go through `LauncherApiClient`. - Launcher bearer tokens must be persisted through `flutter_secure_storage`. Do not store sessions or other secrets in `shared_preferences`. - File sync behavior should stay in `ClientSyncUseCase` and `GameInstallationService`. - Launcher self-update behavior should stay behind `LauncherUpdateService`. Windows updates use WinSparkle/AppCast and the signed Inno Setup artifact; they are separate from game-client synchronization. - The server manifest is the source of truth for client files. - Downloads must write to `*.moonwell.part`, verify size and SHA-256, then replace the destination file only after successful verification. - Local scans should ignore volatile client directories and launcher metadata: `Cache`, `Errors`, `Logs`, `Screenshots`, `WTF`, and `.moonwell_launcher`. - Path normalization and traversal checks are safety-critical. Do not bypass `GameInstallationService.resolveClientPath` for manifest-relative paths. - `lib/service_container.config.dart` is generated by injectable. Do not hand-edit it unless you are intentionally repairing generated output; prefer regenerating it with build_runner. ## Repository Rules - Preserve unrelated work in a dirty tree. This repository currently may have user edits in dependency files. - Keep changes scoped to the requested behavior. - Always keep `README.md` and files under `docs/` up-to-date with any architecture, setup, API, sync, build, or operational change. - Keep documentation links current when files move. - Keep catalog widgets presentation-only. Do not call BLoCs, APIs, storage, file pickers, dependency injection, or native window plugins from them.