Files
moonwell-launcher/AGENTS.md
T
sindoring f834c5fa86 Synchronize the client and select installed language packs (#3)
The launcher synchronizes the current native client, retains manifest-listed ruRU archives and launches the game with WOW_LOCALE=auto. Includes the prepared cleanup of obsolete Extentions directories in both client roots while preserving manifest-required files and unrelated user state.

Version: 1.0.7+10. Deployment now judges native OpenSSL commands by their exit codes while retaining key and signature verification.

Verified on Windows through FVM: full format/analyze, all 76 tests, production dry run, x64 runtime imports and DSA installer signature. The original dirty checkout was preserved. Publication follows the localized client release.
2026-10-10 16:50:35 +03:00

6.0 KiB

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

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:

--dart-define=MOONWELL_API_BASE_URL=https://host

The optional Windows self-update feed is also compile-time configuration:

--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. Also clean obsolete Extentions directories in either client root and remove the directory itself when no manifest files require it. 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.