# 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 1.12.1 server running vMaNGOS. It logs players in, downloads and synchronizes client files, displays launcher news, and starts the Rust MoonWell client (`MoonWell.exe` on Windows or `MoonWell.app` on macOS). 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. `MOONWELL_AUTH_ADDRESS` optionally pins the game's auth endpoint as `host[:port]` (default port 3724). Otherwise it is read from `realmlist.wtf` in the selected installation root. A realm's world port is not the auth port. 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. - Sync removes files absent from the manifest under `Data` and `WoW/Data`, plus legacy `WoW.exe` and DLLs directly in the installation root or `WoW`. Remove unused Data subdirectories only after their children, without recursive deletion. Preserve unrelated files and user state outside these areas. - Language archives under `Data/ruRU` or `WoW/Data/ruRU` use the regular manifest sync. Pass `WOW_LOCALE=auto` to the game so its selected install determines the locale. - 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`. - MoonWell player state lives in `benilla-config` outside the WoW data and, on macOS, outside the application bundle. Exclude it from verification too. - Request game tickets for build 5875. Pass their account and ticket as `WOW_USER` and `WOW_PASS` in the child environment, never in arguments or persistent storage. Starting MoonWell must not edit `WTF/Config.wtf` or clear the install's `Cache`. - 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.