arenamcp 2.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arenamcp-2.8.0/.env.example +28 -0
- arenamcp-2.8.0/.github/workflows/installer.yml +88 -0
- arenamcp-2.8.0/.github/workflows/publish-pypi.yml +46 -0
- arenamcp-2.8.0/.github/workflows/tests.yml +67 -0
- arenamcp-2.8.0/.gitignore +69 -0
- arenamcp-2.8.0/.pre-commit-config.yaml +31 -0
- arenamcp-2.8.0/AGENTS.md +87 -0
- arenamcp-2.8.0/DEV.md +85 -0
- arenamcp-2.8.0/GEMINI.md +158 -0
- arenamcp-2.8.0/INSTALL.md +126 -0
- arenamcp-2.8.0/PKG-INFO +122 -0
- arenamcp-2.8.0/README.md +58 -0
- arenamcp-2.8.0/RELEASE.md +70 -0
- arenamcp-2.8.0/TODO.md +98 -0
- arenamcp-2.8.0/assets/BepInEx/core/0Harmony.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/0Harmony.xml +4288 -0
- arenamcp-2.8.0/assets/BepInEx/core/0Harmony20.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/BepInEx.Harmony.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/BepInEx.Harmony.xml +86 -0
- arenamcp-2.8.0/assets/BepInEx/core/BepInEx.Preloader.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/BepInEx.Preloader.xml +169 -0
- arenamcp-2.8.0/assets/BepInEx/core/BepInEx.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/BepInEx.xml +1737 -0
- arenamcp-2.8.0/assets/BepInEx/core/HarmonyXInterop.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/Mono.Cecil.Mdb.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/Mono.Cecil.Pdb.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/Mono.Cecil.Rocks.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/Mono.Cecil.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/MonoMod.RuntimeDetour.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/MonoMod.RuntimeDetour.xml +178 -0
- arenamcp-2.8.0/assets/BepInEx/core/MonoMod.Utils.dll +0 -0
- arenamcp-2.8.0/assets/BepInEx/core/MonoMod.Utils.xml +1470 -0
- arenamcp-2.8.0/assets/doorstop_config.ini +39 -0
- arenamcp-2.8.0/assets/icon.png +0 -0
- arenamcp-2.8.0/assets/winhttp.dll +0 -0
- arenamcp-2.8.0/bepinex-plugin/MtgaCoachBridge/BotBattleBridge.cs +499 -0
- arenamcp-2.8.0/bepinex-plugin/MtgaCoachBridge/MtgaCoachBridge.csproj +71 -0
- arenamcp-2.8.0/bepinex-plugin/MtgaCoachBridge/MtgaCoachHost.cs +130 -0
- arenamcp-2.8.0/bepinex-plugin/MtgaCoachBridge/Plugin.cs +4815 -0
- arenamcp-2.8.0/bepinex-plugin/MtgaCoachBridge/PracticeMatchBridge.cs +220 -0
- arenamcp-2.8.0/bepinex-plugin/README.md +82 -0
- arenamcp-2.8.0/configs/run_diverse.yml +64 -0
- arenamcp-2.8.0/favicon.ico +0 -0
- arenamcp-2.8.0/gateway/README.md +56 -0
- arenamcp-2.8.0/gateway/config.yaml +92 -0
- arenamcp-2.8.0/gateway/docker-compose.yml +46 -0
- arenamcp-2.8.0/icon.ico +0 -0
- arenamcp-2.8.0/install.bat +43 -0
- arenamcp-2.8.0/installer/build-installer.ps1 +97 -0
- arenamcp-2.8.0/installer/mtga_coach_dev.ico +0 -0
- arenamcp-2.8.0/installer/mtgacoach.iss +195 -0
- arenamcp-2.8.0/launch.bat +104 -0
- arenamcp-2.8.0/launch.vbs +39 -0
- arenamcp-2.8.0/launcher.py +566 -0
- arenamcp-2.8.0/launcher_gui.py +614 -0
- arenamcp-2.8.0/model-survey-2026-07-30.md +465 -0
- arenamcp-2.8.0/mtga_coach.ico +0 -0
- arenamcp-2.8.0/play-real.sh +33 -0
- arenamcp-2.8.0/pyproject.toml +173 -0
- arenamcp-2.8.0/requirements.txt +56 -0
- arenamcp-2.8.0/scripts/build_release.ps1 +85 -0
- arenamcp-2.8.0/scripts/launch_desktop.py +72 -0
- arenamcp-2.8.0/scripts/launch_installed.py +79 -0
- arenamcp-2.8.0/scripts/update_dev_shortcut.py +21 -0
- arenamcp-2.8.0/selfplay.sh +31 -0
- arenamcp-2.8.0/setup_wizard.py +1255 -0
- arenamcp-2.8.0/src/arenamcp/__init__.py +162 -0
- arenamcp-2.8.0/src/arenamcp/action_detector.py +198 -0
- arenamcp-2.8.0/src/arenamcp/action_planner.py +2860 -0
- arenamcp-2.8.0/src/arenamcp/arena_replay.py +346 -0
- arenamcp-2.8.0/src/arenamcp/audio.py +147 -0
- arenamcp-2.8.0/src/arenamcp/autopilot.py +4529 -0
- arenamcp-2.8.0/src/arenamcp/autopilot_bridge.py +1905 -0
- arenamcp-2.8.0/src/arenamcp/autopilot_exec.py +1368 -0
- arenamcp-2.8.0/src/arenamcp/autopilot_models.py +76 -0
- arenamcp-2.8.0/src/arenamcp/autopilot_targets.py +114 -0
- arenamcp-2.8.0/src/arenamcp/backend_detect.py +188 -0
- arenamcp-2.8.0/src/arenamcp/backend_health.py +244 -0
- arenamcp-2.8.0/src/arenamcp/backends/__init__.py +14 -0
- arenamcp-2.8.0/src/arenamcp/backends/base.py +18 -0
- arenamcp-2.8.0/src/arenamcp/backends/proxy.py +732 -0
- arenamcp-2.8.0/src/arenamcp/bugreport.py +247 -0
- arenamcp-2.8.0/src/arenamcp/cache_utils.py +75 -0
- arenamcp-2.8.0/src/arenamcp/card_db.py +655 -0
- arenamcp-2.8.0/src/arenamcp/client_metadata.py +48 -0
- arenamcp-2.8.0/src/arenamcp/coach.py +4115 -0
- arenamcp-2.8.0/src/arenamcp/coach_postprocess.py +1547 -0
- arenamcp-2.8.0/src/arenamcp/coach_prompt_utils.py +314 -0
- arenamcp-2.8.0/src/arenamcp/coach_prompts.py +359 -0
- arenamcp-2.8.0/src/arenamcp/coach_triggers.py +497 -0
- arenamcp-2.8.0/src/arenamcp/combat_solver.py +592 -0
- arenamcp-2.8.0/src/arenamcp/decision_arbiter.py +98 -0
- arenamcp-2.8.0/src/arenamcp/decisions.py +569 -0
- arenamcp-2.8.0/src/arenamcp/deck_builder.py +846 -0
- arenamcp-2.8.0/src/arenamcp/desktop/__init__.py +5 -0
- arenamcp-2.8.0/src/arenamcp/desktop/__main__.py +4 -0
- arenamcp-2.8.0/src/arenamcp/desktop/advice_panel.py +409 -0
- arenamcp-2.8.0/src/arenamcp/desktop/app.py +320 -0
- arenamcp-2.8.0/src/arenamcp/desktop/audio.py +116 -0
- arenamcp-2.8.0/src/arenamcp/desktop/brain_stream_window.py +664 -0
- arenamcp-2.8.0/src/arenamcp/desktop/card_overlay.py +503 -0
- arenamcp-2.8.0/src/arenamcp/desktop/coach_process.py +227 -0
- arenamcp-2.8.0/src/arenamcp/desktop/coach_tab.py +2480 -0
- arenamcp-2.8.0/src/arenamcp/desktop/compact_coach.py +1139 -0
- arenamcp-2.8.0/src/arenamcp/desktop/hotkeys.py +62 -0
- arenamcp-2.8.0/src/arenamcp/desktop/hotkeys_darwin.py +203 -0
- arenamcp-2.8.0/src/arenamcp/desktop/hud.py +458 -0
- arenamcp-2.8.0/src/arenamcp/desktop/main_window.py +1090 -0
- arenamcp-2.8.0/src/arenamcp/desktop/match_overlay.py +1012 -0
- arenamcp-2.8.0/src/arenamcp/desktop/performance_tab.py +230 -0
- arenamcp-2.8.0/src/arenamcp/desktop/repair_tab.py +231 -0
- arenamcp-2.8.0/src/arenamcp/desktop/runtime.py +1219 -0
- arenamcp-2.8.0/src/arenamcp/desktop/setup_splash.py +472 -0
- arenamcp-2.8.0/src/arenamcp/desktop/theme.py +344 -0
- arenamcp-2.8.0/src/arenamcp/desktop/tts_manager.py +362 -0
- arenamcp-2.8.0/src/arenamcp/desktop/tts_worker.py +133 -0
- arenamcp-2.8.0/src/arenamcp/desktop/ui_watchdog.py +103 -0
- arenamcp-2.8.0/src/arenamcp/desktop/window_tracking.py +251 -0
- arenamcp-2.8.0/src/arenamcp/diagnose.py +535 -0
- arenamcp-2.8.0/src/arenamcp/draft_eval.py +787 -0
- arenamcp-2.8.0/src/arenamcp/draft_guidance.py +981 -0
- arenamcp-2.8.0/src/arenamcp/draftstate.py +420 -0
- arenamcp-2.8.0/src/arenamcp/draftstats.py +277 -0
- arenamcp-2.8.0/src/arenamcp/dynamic_cards.py +89 -0
- arenamcp-2.8.0/src/arenamcp/edhrec.py +216 -0
- arenamcp-2.8.0/src/arenamcp/game_plan.py +415 -0
- arenamcp-2.8.0/src/arenamcp/gamestate.py +3133 -0
- arenamcp-2.8.0/src/arenamcp/gamestate_decisions.py +1039 -0
- arenamcp-2.8.0/src/arenamcp/gamestate_models.py +259 -0
- arenamcp-2.8.0/src/arenamcp/gamestate_persistence.py +231 -0
- arenamcp-2.8.0/src/arenamcp/gamestate_transforms.py +228 -0
- arenamcp-2.8.0/src/arenamcp/gre_action_matcher.py +405 -0
- arenamcp-2.8.0/src/arenamcp/gre_bridge.py +2350 -0
- arenamcp-2.8.0/src/arenamcp/gre_serializer.py +673 -0
- arenamcp-2.8.0/src/arenamcp/input_controller.py +871 -0
- arenamcp-2.8.0/src/arenamcp/log_utils.py +197 -0
- arenamcp-2.8.0/src/arenamcp/logging_config.py +79 -0
- arenamcp-2.8.0/src/arenamcp/magezero_client.py +184 -0
- arenamcp-2.8.0/src/arenamcp/match_evaluator.py +233 -0
- arenamcp-2.8.0/src/arenamcp/match_history.py +382 -0
- arenamcp-2.8.0/src/arenamcp/match_packets.py +194 -0
- arenamcp-2.8.0/src/arenamcp/match_review.py +408 -0
- arenamcp-2.8.0/src/arenamcp/match_validator.py +686 -0
- arenamcp-2.8.0/src/arenamcp/mcts_evaluator.py +558 -0
- arenamcp-2.8.0/src/arenamcp/mtgadb.py +628 -0
- arenamcp-2.8.0/src/arenamcp/mtggoldfish.py +194 -0
- arenamcp-2.8.0/src/arenamcp/mtgjson.py +417 -0
- arenamcp-2.8.0/src/arenamcp/opponent_model.py +279 -0
- arenamcp-2.8.0/src/arenamcp/parser.py +347 -0
- arenamcp-2.8.0/src/arenamcp/pipe_adapter.py +1296 -0
- arenamcp-2.8.0/src/arenamcp/platform_integration.py +357 -0
- arenamcp-2.8.0/src/arenamcp/play_real_matches.py +575 -0
- arenamcp-2.8.0/src/arenamcp/proton_launch.py +268 -0
- arenamcp-2.8.0/src/arenamcp/realtime.py +697 -0
- arenamcp-2.8.0/src/arenamcp/repair_cli.py +50 -0
- arenamcp-2.8.0/src/arenamcp/repair_engine.py +646 -0
- arenamcp-2.8.0/src/arenamcp/replay_converter.py +193 -0
- arenamcp-2.8.0/src/arenamcp/request_tracker.py +181 -0
- arenamcp-2.8.0/src/arenamcp/resources/MtgaCoachBridge.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/__init__.py +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/0Harmony.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/0Harmony.xml +4288 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/0Harmony20.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/BepInEx.Harmony.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/BepInEx.Harmony.xml +86 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/BepInEx.Preloader.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/BepInEx.Preloader.xml +169 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/BepInEx.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/BepInEx.xml +1737 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/HarmonyXInterop.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/Mono.Cecil.Mdb.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/Mono.Cecil.Pdb.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/Mono.Cecil.Rocks.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/Mono.Cecil.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/MonoMod.RuntimeDetour.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/MonoMod.RuntimeDetour.xml +178 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/MonoMod.Utils.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/BepInEx/core/MonoMod.Utils.xml +1470 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/doorstop_config.ini +39 -0
- arenamcp-2.8.0/src/arenamcp/resources/bepinex/winhttp.dll +0 -0
- arenamcp-2.8.0/src/arenamcp/rules_data.py +1004 -0
- arenamcp-2.8.0/src/arenamcp/rules_db.py +312 -0
- arenamcp-2.8.0/src/arenamcp/rules_engine.py +1238 -0
- arenamcp-2.8.0/src/arenamcp/screen_capture.py +266 -0
- arenamcp-2.8.0/src/arenamcp/screen_mapper.py +963 -0
- arenamcp-2.8.0/src/arenamcp/scryfall.py +358 -0
- arenamcp-2.8.0/src/arenamcp/sealed_eval.py +310 -0
- arenamcp-2.8.0/src/arenamcp/self_play.py +886 -0
- arenamcp-2.8.0/src/arenamcp/server.py +2620 -0
- arenamcp-2.8.0/src/arenamcp/settings.py +270 -0
- arenamcp-2.8.0/src/arenamcp/stall_corpus.py +68 -0
- arenamcp-2.8.0/src/arenamcp/standalone.py +4213 -0
- arenamcp-2.8.0/src/arenamcp/standalone_deck.py +565 -0
- arenamcp-2.8.0/src/arenamcp/standalone_diagnostics.py +934 -0
- arenamcp-2.8.0/src/arenamcp/standalone_mcp.py +76 -0
- arenamcp-2.8.0/src/arenamcp/standalone_postmatch.py +901 -0
- arenamcp-2.8.0/src/arenamcp/standalone_ui.py +113 -0
- arenamcp-2.8.0/src/arenamcp/standalone_voice.py +232 -0
- arenamcp-2.8.0/src/arenamcp/subscription.py +308 -0
- arenamcp-2.8.0/src/arenamcp/synergy.py +569 -0
- arenamcp-2.8.0/src/arenamcp/trajectory_recorder.py +253 -0
- arenamcp-2.8.0/src/arenamcp/transcription.py +115 -0
- arenamcp-2.8.0/src/arenamcp/triggers.py +225 -0
- arenamcp-2.8.0/src/arenamcp/tts.py +924 -0
- arenamcp-2.8.0/src/arenamcp/updater.py +183 -0
- arenamcp-2.8.0/src/arenamcp/vision_mapper.py +1006 -0
- arenamcp-2.8.0/src/arenamcp/voice.py +294 -0
- arenamcp-2.8.0/src/arenamcp/watcher.py +654 -0
- arenamcp-2.8.0/tests/conftest.py +50 -0
- arenamcp-2.8.0/tests/fixtures/stalls/momentum_breaker_unpayable.json +19 -0
- arenamcp-2.8.0/tests/fixtures/stalls/nurturing_presence_select_targets.json +17 -0
- arenamcp-2.8.0/tests/fixtures/stalls/ruthless_negotiation_player_target.json +17 -0
- arenamcp-2.8.0/tests/test_ability_affordability.py +441 -0
- arenamcp-2.8.0/tests/test_ability_source_naming.py +109 -0
- arenamcp-2.8.0/tests/test_action_planner_land_drop_first.py +116 -0
- arenamcp-2.8.0/tests/test_action_planner_legality.py +189 -0
- arenamcp-2.8.0/tests/test_action_planner_turn_intent.py +199 -0
- arenamcp-2.8.0/tests/test_action_planner_turn_plan.py +375 -0
- arenamcp-2.8.0/tests/test_actions_available_typed.py +88 -0
- arenamcp-2.8.0/tests/test_attack_tax.py +100 -0
- arenamcp-2.8.0/tests/test_autopilot_bridge_attackers.py +254 -0
- arenamcp-2.8.0/tests/test_autopilot_bridge_gap_hint.py +101 -0
- arenamcp-2.8.0/tests/test_autopilot_bridge_lock.py +518 -0
- arenamcp-2.8.0/tests/test_autopilot_card_name_normalize.py +78 -0
- arenamcp-2.8.0/tests/test_autopilot_livelock.py +355 -0
- arenamcp-2.8.0/tests/test_autopilot_optional_cost_gate.py +145 -0
- arenamcp-2.8.0/tests/test_autopilot_safe_default_group.py +171 -0
- arenamcp-2.8.0/tests/test_autopilot_solver_attacks.py +139 -0
- arenamcp-2.8.0/tests/test_autopilot_stale_vs_bridge.py +382 -0
- arenamcp-2.8.0/tests/test_backend_health.py +277 -0
- arenamcp-2.8.0/tests/test_baseline_plan.py +132 -0
- arenamcp-2.8.0/tests/test_battlefield_land_oracle.py +221 -0
- arenamcp-2.8.0/tests/test_block_advice_specificity.py +333 -0
- arenamcp-2.8.0/tests/test_brain_stream_window.py +307 -0
- arenamcp-2.8.0/tests/test_bridge_blocker_enrichment.py +193 -0
- arenamcp-2.8.0/tests/test_bridge_offline_recovery.py +176 -0
- arenamcp-2.8.0/tests/test_bridge_prompt_enrichment.py +235 -0
- arenamcp-2.8.0/tests/test_bridge_x_chooser.py +368 -0
- arenamcp-2.8.0/tests/test_bugreport.py +112 -0
- arenamcp-2.8.0/tests/test_build_curriculum.py +247 -0
- arenamcp-2.8.0/tests/test_build_dataset_contracts.py +32 -0
- arenamcp-2.8.0/tests/test_build_mixture_manifest.py +232 -0
- arenamcp-2.8.0/tests/test_build_play_decisions.py +476 -0
- arenamcp-2.8.0/tests/test_build_strategic_casts.py +231 -0
- arenamcp-2.8.0/tests/test_card_db_type_lines.py +283 -0
- arenamcp-2.8.0/tests/test_card_overlay_badges.py +44 -0
- arenamcp-2.8.0/tests/test_card_prewarming.py +77 -0
- arenamcp-2.8.0/tests/test_coach_advice_matching.py +201 -0
- arenamcp-2.8.0/tests/test_coach_postprocess_color_castability.py +121 -0
- arenamcp-2.8.0/tests/test_coach_postprocess_lands.py +208 -0
- arenamcp-2.8.0/tests/test_combat_balance.py +260 -0
- arenamcp-2.8.0/tests/test_combat_label_integrity.py +126 -0
- arenamcp-2.8.0/tests/test_compact_coach.py +107 -0
- arenamcp-2.8.0/tests/test_contract_validators.py +58 -0
- arenamcp-2.8.0/tests/test_corpus_selfcheck.py +300 -0
- arenamcp-2.8.0/tests/test_decision_arbiter.py +108 -0
- arenamcp-2.8.0/tests/test_decisions.py +155 -0
- arenamcp-2.8.0/tests/test_deck_builder_tiered.py +118 -0
- arenamcp-2.8.0/tests/test_deck_inventory.py +247 -0
- arenamcp-2.8.0/tests/test_desktop_audio.py +43 -0
- arenamcp-2.8.0/tests/test_desktop_hotkeys.py +73 -0
- arenamcp-2.8.0/tests/test_desktop_runtime.py +105 -0
- arenamcp-2.8.0/tests/test_desktop_runtime_darwin.py +436 -0
- arenamcp-2.8.0/tests/test_draft_eval_preference_locking.py +89 -0
- arenamcp-2.8.0/tests/test_draft_guidance.py +578 -0
- arenamcp-2.8.0/tests/test_draft_guidance_wiring.py +7 -0
- arenamcp-2.8.0/tests/test_dynamic_cards.py +85 -0
- arenamcp-2.8.0/tests/test_equip_target_selection.py +41 -0
- arenamcp-2.8.0/tests/test_eval_pipeline_smoke.py +202 -0
- arenamcp-2.8.0/tests/test_eval_run_backend_binding.py +152 -0
- arenamcp-2.8.0/tests/test_fail_closed_gating.py +259 -0
- arenamcp-2.8.0/tests/test_fallback_tagging.py +265 -0
- arenamcp-2.8.0/tests/test_game_plan.py +181 -0
- arenamcp-2.8.0/tests/test_gamestate_checkpoint.py +142 -0
- arenamcp-2.8.0/tests/test_gamestate_gre_normalization.py +219 -0
- arenamcp-2.8.0/tests/test_gamestate_lands_played_inference.py +149 -0
- arenamcp-2.8.0/tests/test_gate_combat_decisions.py +751 -0
- arenamcp-2.8.0/tests/test_gate_play_decisions.py +871 -0
- arenamcp-2.8.0/tests/test_gate_stats.py +25 -0
- arenamcp-2.8.0/tests/test_gre_bridge_read_timeout.py +144 -0
- arenamcp-2.8.0/tests/test_health_tag_visibility.py +201 -0
- arenamcp-2.8.0/tests/test_hotkeys_and_vision_darwin.py +220 -0
- arenamcp-2.8.0/tests/test_ingest_manasight.py +854 -0
- arenamcp-2.8.0/tests/test_input_controller_virtual_screen.py +74 -0
- arenamcp-2.8.0/tests/test_library_summary.py +122 -0
- arenamcp-2.8.0/tests/test_litellm_exporter.py +186 -0
- arenamcp-2.8.0/tests/test_magezero_bridge_leaks.py +267 -0
- arenamcp-2.8.0/tests/test_magezero_card_map.py +261 -0
- arenamcp-2.8.0/tests/test_magezero_combat.py +374 -0
- arenamcp-2.8.0/tests/test_magezero_combat_micro.py +477 -0
- arenamcp-2.8.0/tests/test_magezero_filters.py +699 -0
- arenamcp-2.8.0/tests/test_magezero_hdf5_to_corpus.py +178 -0
- arenamcp-2.8.0/tests/test_manual_play_detect_p14.py +68 -0
- arenamcp-2.8.0/tests/test_match_evaluator.py +152 -0
- arenamcp-2.8.0/tests/test_match_packets.py +150 -0
- arenamcp-2.8.0/tests/test_match_packets_p09.py +49 -0
- arenamcp-2.8.0/tests/test_match_review.py +139 -0
- arenamcp-2.8.0/tests/test_match_state_resume.py +32 -0
- arenamcp-2.8.0/tests/test_match_weighted_win_rate.py +219 -0
- arenamcp-2.8.0/tests/test_mcts_evaluator.py +336 -0
- arenamcp-2.8.0/tests/test_meaningful_advice_filter.py +283 -0
- arenamcp-2.8.0/tests/test_menu_pick_r3.py +189 -0
- arenamcp-2.8.0/tests/test_model_registry.py +286 -0
- arenamcp-2.8.0/tests/test_mtgadb.py +179 -0
- arenamcp-2.8.0/tests/test_mulligan_advice_guard.py +118 -0
- arenamcp-2.8.0/tests/test_mulligan_deck_analysis_order.py +86 -0
- arenamcp-2.8.0/tests/test_multi_spell_postprocess.py +187 -0
- arenamcp-2.8.0/tests/test_no_provision_splash.py +23 -0
- arenamcp-2.8.0/tests/test_oracle_coverage.py +268 -0
- arenamcp-2.8.0/tests/test_paired_bootstrap.py +28 -0
- arenamcp-2.8.0/tests/test_parse_magezero_log.py +1233 -0
- arenamcp-2.8.0/tests/test_patreon_litellm.py +199 -0
- arenamcp-2.8.0/tests/test_pay_costs_flow.py +261 -0
- arenamcp-2.8.0/tests/test_pay_costs_race.py +127 -0
- arenamcp-2.8.0/tests/test_performance_tab.py +234 -0
- arenamcp-2.8.0/tests/test_pipe_voice_output.py +63 -0
- arenamcp-2.8.0/tests/test_plan_framing_gate.py +49 -0
- arenamcp-2.8.0/tests/test_planner_combat_voice.py +50 -0
- arenamcp-2.8.0/tests/test_platform_darwin.py +282 -0
- arenamcp-2.8.0/tests/test_proxy_backend_errors.py +125 -0
- arenamcp-2.8.0/tests/test_proxy_backend_timeout.py +81 -0
- arenamcp-2.8.0/tests/test_proxy_reasoning_salvage.py +109 -0
- arenamcp-2.8.0/tests/test_proxy_server_responses.py +242 -0
- arenamcp-2.8.0/tests/test_proxy_server_signup.py +91 -0
- arenamcp-2.8.0/tests/test_proxy_thinking_control.py +93 -0
- arenamcp-2.8.0/tests/test_queue_bot_match.py +44 -0
- arenamcp-2.8.0/tests/test_raw_card_token_resolution.py +104 -0
- arenamcp-2.8.0/tests/test_release_versioning.py +226 -0
- arenamcp-2.8.0/tests/test_repair_darwin.py +283 -0
- arenamcp-2.8.0/tests/test_repair_engine.py +115 -0
- arenamcp-2.8.0/tests/test_replay_seat_detection.py +340 -0
- arenamcp-2.8.0/tests/test_request_tracker.py +121 -0
- arenamcp-2.8.0/tests/test_run_wp3_pipeline.py +132 -0
- arenamcp-2.8.0/tests/test_self_play_orchestrator.py +80 -0
- arenamcp-2.8.0/tests/test_self_play_recording.py +336 -0
- arenamcp-2.8.0/tests/test_server_bridge_overlay.py +311 -0
- arenamcp-2.8.0/tests/test_settings_scryfall.py +209 -0
- arenamcp-2.8.0/tests/test_sideboard_and_analyze.py +292 -0
- arenamcp-2.8.0/tests/test_stack_and_solver_prompt.py +327 -0
- arenamcp-2.8.0/tests/test_stall_corpus.py +47 -0
- arenamcp-2.8.0/tests/test_standalone_draft_hud.py +97 -0
- arenamcp-2.8.0/tests/test_standalone_generic_selection.py +68 -0
- arenamcp-2.8.0/tests/test_standalone_speak_advice.py +55 -0
- arenamcp-2.8.0/tests/test_state_replay.py +114 -0
- arenamcp-2.8.0/tests/test_takeover_reclassify_p18.py +63 -0
- arenamcp-2.8.0/tests/test_target_selection_disjunction.py +159 -0
- arenamcp-2.8.0/tests/test_target_selection_grounding.py +219 -0
- arenamcp-2.8.0/tests/test_target_selection_regressions.py +391 -0
- arenamcp-2.8.0/tests/test_target_selection_scoring.py +122 -0
- arenamcp-2.8.0/tests/test_targeting_fallback_decline.py +172 -0
- arenamcp-2.8.0/tests/test_taxonomy.py +770 -0
- arenamcp-2.8.0/tests/test_temperature_fallback.py +19 -0
- arenamcp-2.8.0/tests/test_threat_advice.py +404 -0
- arenamcp-2.8.0/tests/test_train_chat_template.py +86 -0
- arenamcp-2.8.0/tests/test_train_ddp.py +73 -0
- arenamcp-2.8.0/tests/test_train_early_stopping.py +140 -0
- arenamcp-2.8.0/tests/test_trial_client.py +171 -0
- arenamcp-2.8.0/tests/test_trial_endpoint.py +208 -0
- arenamcp-2.8.0/tests/test_typed_decision_path.py +265 -0
- arenamcp-2.8.0/tests/test_unseen_deck_gate.py +609 -0
- arenamcp-2.8.0/tests/test_validate_run_config.py +163 -0
- arenamcp-2.8.0/tests/test_validators.py +298 -0
- arenamcp-2.8.0/tests/test_voice_darwin.py +262 -0
- arenamcp-2.8.0/tests/test_watcher_startup.py +93 -0
- arenamcp-2.8.0/tests/test_window_identity_r1.py +170 -0
- arenamcp-2.8.0/tests/test_window_tracking.py +457 -0
- arenamcp-2.8.0/tests/test_x_chooser_plumbing.py +162 -0
- arenamcp-2.8.0/tools/eval/README.md +174 -0
- arenamcp-2.8.0/tools/eval/__init__.py +1 -0
- arenamcp-2.8.0/tools/eval/auto.py +396 -0
- arenamcp-2.8.0/tools/eval/bot_battle/__init__.py +0 -0
- arenamcp-2.8.0/tools/eval/bot_battle/smoke_test.py +99 -0
- arenamcp-2.8.0/tools/eval/build_corpus.py +47 -0
- arenamcp-2.8.0/tools/eval/coach_prompt_ablation.py +240 -0
- arenamcp-2.8.0/tools/eval/forge_fidelity.py +1317 -0
- arenamcp-2.8.0/tools/eval/judge.py +237 -0
- arenamcp-2.8.0/tools/eval/replay/__init__.py +0 -0
- arenamcp-2.8.0/tools/eval/replay/decisions.py +297 -0
- arenamcp-2.8.0/tools/eval/replay/menu_groundtruth.py +1369 -0
- arenamcp-2.8.0/tools/eval/replay/prompts.py +684 -0
- arenamcp-2.8.0/tools/eval/replay/reader.py +211 -0
- arenamcp-2.8.0/tools/eval/replay/run.py +589 -0
- arenamcp-2.8.0/tools/eval/replay/score.py +454 -0
- arenamcp-2.8.0/tools/eval/replay/state.py +346 -0
- arenamcp-2.8.0/tools/eval/replay/strategic_groundtruth.py +1391 -0
- arenamcp-2.8.0/tools/eval/replay_stalls.py +111 -0
- arenamcp-2.8.0/tools/eval/report.py +204 -0
- arenamcp-2.8.0/tools/eval/run.py +300 -0
- arenamcp-2.8.0/tools/eval/run_baseline.py +104 -0
- arenamcp-2.8.0/tools/eval/seventeenlands/README.md +134 -0
- arenamcp-2.8.0/tools/eval/seventeenlands/__init__.py +5 -0
- arenamcp-2.8.0/tools/eval/seventeenlands/build_mulligan_prompts.py +411 -0
- arenamcp-2.8.0/tools/eval/seventeenlands/build_turn_action_prompts.py +524 -0
- arenamcp-2.8.0/tools/eval/seventeenlands/download.py +115 -0
- arenamcp-2.8.0/tools/eval/seventeenlands/loader.py +115 -0
- arenamcp-2.8.0/tools/eval/seventeenlands/score_mulligan.py +335 -0
- arenamcp-2.8.0/tools/eval/seventeenlands/score_turn_actions.py +276 -0
- arenamcp-2.8.0/tools/eval/upload_results.py +63 -0
- arenamcp-2.8.0/tools/monitoring/grafana/apply_dashboards.sh +92 -0
- arenamcp-2.8.0/tools/monitoring/grafana/gpu-fleet.json +2889 -0
- arenamcp-2.8.0/tools/monitoring/grafana/vllm-gemma.json +1884 -0
- arenamcp-2.8.0/tools/monitoring/litellm_exporter/README.md +68 -0
- arenamcp-2.8.0/tools/monitoring/litellm_exporter/exporter.py +297 -0
- arenamcp-2.8.0/tools/training/_dryrun_prompt_debug.py +101 -0
- arenamcp-2.8.0/tools/training/build_bridge_dataset.py +729 -0
- arenamcp-2.8.0/tools/training/build_combat_decisions.py +2403 -0
- arenamcp-2.8.0/tools/training/build_curriculum.py +929 -0
- arenamcp-2.8.0/tools/training/build_dataset.py +589 -0
- arenamcp-2.8.0/tools/training/build_gate_corpus_v2.py +184 -0
- arenamcp-2.8.0/tools/training/build_magezero_bridge.py +713 -0
- arenamcp-2.8.0/tools/training/build_magezero_combat.py +939 -0
- arenamcp-2.8.0/tools/training/build_play_decisions.py +988 -0
- arenamcp-2.8.0/tools/training/build_strategic_casts.py +979 -0
- arenamcp-2.8.0/tools/training/build_tripwires.py +307 -0
- arenamcp-2.8.0/tools/training/corpus_selfcheck.py +264 -0
- arenamcp-2.8.0/tools/training/extract_real_menus.py +180 -0
- arenamcp-2.8.0/tools/training/formatting.py +72 -0
- arenamcp-2.8.0/tools/training/gate_combat_decisions.py +2229 -0
- arenamcp-2.8.0/tools/training/gate_level_one.py +220 -0
- arenamcp-2.8.0/tools/training/gate_level_one_quiz.py +274 -0
- arenamcp-2.8.0/tools/training/gate_play_decisions.py +2479 -0
- arenamcp-2.8.0/tools/training/gate_quiz_local.py +130 -0
- arenamcp-2.8.0/tools/training/gate_stage0.py +458 -0
- arenamcp-2.8.0/tools/training/ingest_17lands.py +362 -0
- arenamcp-2.8.0/tools/training/ingest_manasight.py +1623 -0
- arenamcp-2.8.0/tools/training/magezero_actions.py +130 -0
- arenamcp-2.8.0/tools/training/magezero_card_map.json +986 -0
- arenamcp-2.8.0/tools/training/magezero_combat_micro.py +1050 -0
- arenamcp-2.8.0/tools/training/magezero_filters.py +553 -0
- arenamcp-2.8.0/tools/training/magezero_hdf5_to_corpus.py +344 -0
- arenamcp-2.8.0/tools/training/measure_prompt_lengths.py +67 -0
- arenamcp-2.8.0/tools/training/menu_fidelity.py +681 -0
- arenamcp-2.8.0/tools/training/mine_level_one_skills.py +1452 -0
- arenamcp-2.8.0/tools/training/mine_strategic_tripwires.py +741 -0
- arenamcp-2.8.0/tools/training/oracle_coverage.py +456 -0
- arenamcp-2.8.0/tools/training/parse_magezero_log.py +1296 -0
- arenamcp-2.8.0/tools/training/registry.py +454 -0
- arenamcp-2.8.0/tools/training/relabel_dsv4.py +459 -0
- arenamcp-2.8.0/tools/training/run_pipeline.py +637 -0
- arenamcp-2.8.0/tools/training/run_wp3_pipeline.py +1127 -0
- arenamcp-2.8.0/tools/training/split_combat_gate.py +673 -0
- arenamcp-2.8.0/tools/training/synthesize_menu.py +1067 -0
- arenamcp-2.8.0/tools/training/taxonomy/__init__.py +1 -0
- arenamcp-2.8.0/tools/training/taxonomy/annotate.py +176 -0
- arenamcp-2.8.0/tools/training/taxonomy/build_taxonomy.py +944 -0
- arenamcp-2.8.0/tools/training/taxonomy/card_taxonomy.json +385226 -0
- arenamcp-2.8.0/tools/training/train.py +537 -0
- arenamcp-2.8.0/tools/training/validators.py +220 -0
- arenamcp-2.8.0/tools/training/wp3/B5_ROCM_FEASIBILITY.md +183 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-build_magezero_bridge.md +31 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-cuda-serving.md +121 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-distributed-runner.md +147 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-qwen-c1-verify.md +98 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-qwen-c2-latency.md +363 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-qwen-c6-command-zone.md +34 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-qwen-c8-xchooser-verify.md +54 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-smoke.md +149 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-b1-parser.md +109 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-b2-filters.md +49 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-baseline-arm.md +50 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-card-map.md +48 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-combat-adapter.md +80 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-combat-adapter2.md +175 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-combat-rebalance.md +51 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-deck-diversity.md +48 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-gate-eval-prep.md +143 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-hand-attribution.md +119 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-integration.md +69 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-issue-triage.md +46 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-issue-triage2.md +34 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-menu-parity.md +121 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-next-run-prep.md +167 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-oracle-coverage.md +154 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-taxonomy.md +18 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wp3-unseen-gate-slice.md +134 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wt-bridge-x-chooser.md +54 -0
- arenamcp-2.8.0/tools/training/wp3/PROGRESS-wt-gpu-dashboard.md +70 -0
- arenamcp-2.8.0/tools/training/wp3/TEACHER_AUDITION.md +153 -0
- arenamcp-2.8.0/tools/training/wp3/baseline_plan.py +191 -0
- arenamcp-2.8.0/tools/training/wp3/build_mixture_manifest.py +582 -0
- arenamcp-2.8.0/tools/training/wp3/build_unseen_gate_corpus.py +524 -0
- arenamcp-2.8.0/tools/training/wp3/deck_inventory.json +573 -0
- arenamcp-2.8.0/tools/training/wp3/deck_inventory.md +91 -0
- arenamcp-2.8.0/tools/training/wp3/deck_inventory.py +476 -0
- arenamcp-2.8.0/tools/training/wp3/enrich_card_map.py +219 -0
- arenamcp-2.8.0/tools/training/wp3/fixture_bridge_out.jsonl +14 -0
- arenamcp-2.8.0/tools/training/wp3/fixture_combat_decisions.jsonl +14 -0
- arenamcp-2.8.0/tools/training/wp3/fixture_decisions.jsonl +20 -0
- arenamcp-2.8.0/tools/training/wp3/fixtures/fixture_combat_interleaved.log +261 -0
- arenamcp-2.8.0/tools/training/wp3/issue-triage.md +185 -0
- arenamcp-2.8.0/tools/training/wp3/mz_budget_sweep.py +147 -0
- arenamcp-2.8.0/tools/training/wp3/next_run_diverse.yml +77 -0
- arenamcp-2.8.0/tools/training/wp3/resolve_cards.py +200 -0
- arenamcp-2.8.0/tools/training/wp3/run_b5_gate_eval.py +986 -0
- arenamcp-2.8.0/tools/training/wp3/run_baseline.yml +50 -0
- arenamcp-2.8.0/tools/training/wp3/sample_combat_records.py +62 -0
- arenamcp-2.8.0/tools/training/wp3/score_tripwires.py +154 -0
- arenamcp-2.8.0/tools/training/wp3/sweep_base_two_server.yml +71 -0
- arenamcp-2.8.0/tools/training/wp3/validate_run_config.py +158 -0
- arenamcp-2.8.0/tools/training/wp_audit.md +194 -0
- arenamcp-2.8.0/uv.lock +6691 -0
- arenamcp-2.8.0/website/.env.example +18 -0
- arenamcp-2.8.0/website/Dockerfile +23 -0
- arenamcp-2.8.0/website/SETUP.md +192 -0
- arenamcp-2.8.0/website/app.py +1942 -0
- arenamcp-2.8.0/website/config.yaml +64 -0
- arenamcp-2.8.0/website/db.py +598 -0
- arenamcp-2.8.0/website/docker-compose.yml +18 -0
- arenamcp-2.8.0/website/patreon.py +476 -0
- arenamcp-2.8.0/website/providers.py +251 -0
- arenamcp-2.8.0/website/requirements.txt +6 -0
- arenamcp-2.8.0/website/templates/admin.html +2174 -0
- arenamcp-2.8.0/website/templates/landing.html +333 -0
- arenamcp-2.8.0/website/templates/subscribe.html +250 -0
- arenamcp-2.8.0/windows_integration.py +681 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# mtgacoach Configuration
|
|
2
|
+
# Copy this file to .env and configure as needed
|
|
3
|
+
|
|
4
|
+
# License key for online mode (mtgacoach.com)
|
|
5
|
+
# Get yours at https://mtgacoach.com/subscribe
|
|
6
|
+
# Can also be set via the TUI with: /key YOUR_LICENSE_KEY
|
|
7
|
+
# MTGACOACH_LICENSE_KEY=
|
|
8
|
+
|
|
9
|
+
# Local model configuration (vLLM by default; Ollama / LM Studio also supported)
|
|
10
|
+
# These can also be set via the TUI with: /local
|
|
11
|
+
# Default vLLM chat endpoint:
|
|
12
|
+
# LOCAL_URL=http://localhost:8000/v1
|
|
13
|
+
# LOCAL_MODEL=gemma4:e2b
|
|
14
|
+
# To fall back to Ollama, point LOCAL_URL at port 11434 instead:
|
|
15
|
+
# LOCAL_URL=http://localhost:11434/v1
|
|
16
|
+
# LOCAL_MODEL=llama3.2
|
|
17
|
+
|
|
18
|
+
# Optional embeddings endpoint (vLLM container at :8001 serving nomic-embed-text)
|
|
19
|
+
# EMBEDDING_URL=http://localhost:8001/v1
|
|
20
|
+
# EMBEDDING_MODEL=nomic-embed-text
|
|
21
|
+
|
|
22
|
+
# Launcher maintenance
|
|
23
|
+
# Automatically trim Player.log before launch when MTGA is not already running.
|
|
24
|
+
ARENAMCP_TRIM_PLAYER_LOG=1
|
|
25
|
+
# Trim when Player.log exceeds this size in MB.
|
|
26
|
+
ARENAMCP_PLAYER_LOG_MAX_MB=64
|
|
27
|
+
# Keep the newest tail of Player.log at this size in MB.
|
|
28
|
+
ARENAMCP_PLAYER_LOG_KEEP_MB=8
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: build-installer
|
|
2
|
+
|
|
3
|
+
# Builds mtgacoach-Setup.exe on a Windows runner and attaches it to the
|
|
4
|
+
# release for the pushed tag, alongside the Python wheel (.whl) artifact.
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
tags: ["v*"]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
inputs:
|
|
10
|
+
release_tag:
|
|
11
|
+
description: "Existing release tag to attach the installer to (e.g. v2.4.0)"
|
|
12
|
+
required: false
|
|
13
|
+
default: ""
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
installer:
|
|
17
|
+
runs-on: windows-latest
|
|
18
|
+
permissions:
|
|
19
|
+
contents: write
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
|
|
28
|
+
- name: Install build dependencies
|
|
29
|
+
run: |
|
|
30
|
+
python -m pip install --upgrade pip
|
|
31
|
+
pip install build hatchling pyinstaller
|
|
32
|
+
pip install -e .[desktop,full]
|
|
33
|
+
|
|
34
|
+
- name: Build Python wheel
|
|
35
|
+
run: python -m build --wheel
|
|
36
|
+
|
|
37
|
+
- name: Build standalone executable (PyInstaller)
|
|
38
|
+
run: pyinstaller mtgacoach.spec --noconfirm
|
|
39
|
+
|
|
40
|
+
- name: Install Inno Setup
|
|
41
|
+
run: choco install innosetup --no-progress -y
|
|
42
|
+
|
|
43
|
+
- name: Build installer
|
|
44
|
+
shell: pwsh
|
|
45
|
+
run: |
|
|
46
|
+
# Version source of truth: src/arenamcp/__init__.py. pyproject.toml
|
|
47
|
+
# uses hatch dynamic versioning and has no literal `version = "..."`
|
|
48
|
+
# line, so the old fallback could never resolve a version.
|
|
49
|
+
$versionMatch = Select-String -Path "src\arenamcp\__init__.py" -Pattern '^\s*__version__\s*=\s*"([^"]+)"' | Select-Object -First 1
|
|
50
|
+
if (-not $versionMatch) { throw "Could not read __version__ from src/arenamcp/__init__.py" }
|
|
51
|
+
$packageVersion = $versionMatch.Matches[0].Groups[1].Value
|
|
52
|
+
|
|
53
|
+
$version = "${{ inputs.release_tag || github.ref_name }}".TrimStart("v")
|
|
54
|
+
if ($version -notmatch '^\d') { $version = $packageVersion }
|
|
55
|
+
if ($version -ne $packageVersion) {
|
|
56
|
+
Write-Host "::warning::Release tag version '$version' does not match package __version__ '$packageVersion' - the installer asset will be stamped '$version'."
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /DAppVersion=$version installer\mtgacoach.iss
|
|
60
|
+
if (-not (Test-Path dist\installer\mtgacoach-Setup.exe)) { throw "installer not produced" }
|
|
61
|
+
|
|
62
|
+
- name: Attach to release
|
|
63
|
+
if: startsWith(github.ref, 'refs/tags/') || inputs.release_tag != ''
|
|
64
|
+
shell: pwsh
|
|
65
|
+
env:
|
|
66
|
+
GH_TOKEN: ${{ github.token }}
|
|
67
|
+
run: |
|
|
68
|
+
$tag = "${{ inputs.release_tag }}"
|
|
69
|
+
if (-not $tag) { $tag = "${{ github.ref_name }}" }
|
|
70
|
+
gh release upload "$tag" dist/installer/mtgacoach-Setup.exe --clobber
|
|
71
|
+
Get-ChildItem -Path dist\*.whl | ForEach-Object {
|
|
72
|
+
gh release upload "$tag" $_.FullName --clobber
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
- name: Upload installer artifact (non-tag runs)
|
|
76
|
+
if: ${{ !startsWith(github.ref, 'refs/tags/') && inputs.release_tag == '' }}
|
|
77
|
+
uses: actions/upload-artifact@v4
|
|
78
|
+
with:
|
|
79
|
+
name: mtgacoach-Setup
|
|
80
|
+
path: dist/installer/mtgacoach-Setup.exe
|
|
81
|
+
|
|
82
|
+
- name: Upload wheel artifact (non-tag runs)
|
|
83
|
+
if: ${{ !startsWith(github.ref, 'refs/tags/') && inputs.release_tag == '' }}
|
|
84
|
+
uses: actions/upload-artifact@v4
|
|
85
|
+
with:
|
|
86
|
+
name: mtgacoach-wheel
|
|
87
|
+
path: dist/*.whl
|
|
88
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: publish-pypi
|
|
2
|
+
|
|
3
|
+
# Publishes arenamcp to PyPI when a GitHub Release is published, using PyPI
|
|
4
|
+
# Trusted Publishing (OIDC) — no API token is stored anywhere.
|
|
5
|
+
#
|
|
6
|
+
# ONE-TIME SETUP (pypi.org web UI): Account → Publishing → "Add a new
|
|
7
|
+
# pending publisher":
|
|
8
|
+
# PyPI project name: arenamcp
|
|
9
|
+
# Owner: josharmour
|
|
10
|
+
# Repository: mtgacoach
|
|
11
|
+
# Workflow name: publish-pypi.yml
|
|
12
|
+
# Environment: pypi
|
|
13
|
+
# After the first successful publish the pending publisher becomes permanent.
|
|
14
|
+
|
|
15
|
+
on:
|
|
16
|
+
release:
|
|
17
|
+
types: [published]
|
|
18
|
+
workflow_dispatch:
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
build:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
- run: python -m pip install --upgrade build
|
|
29
|
+
- run: python -m build
|
|
30
|
+
- uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
needs: build
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
environment: pypi
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write # OIDC token for Trusted Publishing
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/download-artifact@v4
|
|
43
|
+
with:
|
|
44
|
+
name: dist
|
|
45
|
+
path: dist/
|
|
46
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: tests
|
|
2
|
+
|
|
3
|
+
# The single CI workflow: one pytest run, one ruff run, per push/PR.
|
|
4
|
+
#
|
|
5
|
+
# 2026-07-24 consolidation: this ran alongside ci.yml, and BOTH executed the
|
|
6
|
+
# full ~700-test suite on every push to master with divergent configs
|
|
7
|
+
# (ci.yml: Python 3.11 + .[dev,full]; tests.yml: Python 3.12 + .[dev]).
|
|
8
|
+
# That doubled CI cost and, worse, meant a change could be green in one
|
|
9
|
+
# environment and red in the other. ci.yml has been removed; its
|
|
10
|
+
# dev+full extras (which match the local dev environment the test baseline
|
|
11
|
+
# is measured in) were folded in here.
|
|
12
|
+
#
|
|
13
|
+
# Platform-specific tests (Windows/macOS-only) rely on their own skip guards.
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [master, main]
|
|
17
|
+
pull_request:
|
|
18
|
+
|
|
19
|
+
concurrency:
|
|
20
|
+
group: tests-${{ github.ref }}
|
|
21
|
+
cancel-in-progress: true
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
pytest:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 30
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: "3.12"
|
|
33
|
+
cache: pip
|
|
34
|
+
|
|
35
|
+
# sounddevice -> portaudio, soundfile -> libsndfile, PySide6 offscreen -> GL/xkb
|
|
36
|
+
- name: System dependencies (Qt offscreen + audio libs)
|
|
37
|
+
run: |
|
|
38
|
+
sudo apt-get update
|
|
39
|
+
sudo apt-get install -y --no-install-recommends \
|
|
40
|
+
libportaudio2 libsndfile1 \
|
|
41
|
+
libgl1 libegl1 libxkbcommon0 libdbus-1-3 libfontconfig1
|
|
42
|
+
|
|
43
|
+
- name: Install package with dev + full extras
|
|
44
|
+
run: |
|
|
45
|
+
python -m pip install --upgrade pip
|
|
46
|
+
python -m pip install -e ".[dev,full]"
|
|
47
|
+
|
|
48
|
+
- name: Run tests
|
|
49
|
+
env:
|
|
50
|
+
ARENAMCP_LOG_FILE: /tmp/arenamcp-pytest.log
|
|
51
|
+
QT_QPA_PLATFORM: offscreen
|
|
52
|
+
run: python -m pytest tests -q --tb=short
|
|
53
|
+
|
|
54
|
+
ruff:
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
timeout-minutes: 10
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
# Pinned: the repo is formatted with 0.15.22. Older pins format
|
|
60
|
+
# differently (0.15.2) or cannot parse [tool.ruff.lint] at all (0.6.9
|
|
61
|
+
# rejects the UP045 selector), so an unpinned/stale ruff fails CI on
|
|
62
|
+
# correctly-formatted code.
|
|
63
|
+
- uses: astral-sh/ruff-action@v3
|
|
64
|
+
with:
|
|
65
|
+
version: "0.15.22"
|
|
66
|
+
- run: ruff check src tests
|
|
67
|
+
- run: ruff format --check src tests
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
.env
|
|
2
|
+
.env.*
|
|
3
|
+
!.env.example
|
|
4
|
+
tmpclaude-*
|
|
5
|
+
__pycache__/
|
|
6
|
+
.venv/
|
|
7
|
+
tools/training/wp3/scryfall_cache.json
|
|
8
|
+
tools/training/data/wp3/
|
|
9
|
+
*.pyc
|
|
10
|
+
debug_log.txt
|
|
11
|
+
log_tail.txt
|
|
12
|
+
last_match_event.txt
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
.codex/
|
|
17
|
+
.claude/
|
|
18
|
+
re-output/
|
|
19
|
+
nul
|
|
20
|
+
@eaDir/
|
|
21
|
+
*.planning/
|
|
22
|
+
bug_reports/
|
|
23
|
+
# Synology/deployment configs
|
|
24
|
+
docker-compose.yml
|
|
25
|
+
config.yaml
|
|
26
|
+
*.db
|
|
27
|
+
data/
|
|
28
|
+
# ...except tracked infra-as-code (no secrets; env refs only)
|
|
29
|
+
!gateway/config.yaml
|
|
30
|
+
!gateway/docker-compose.yml
|
|
31
|
+
!website/config.yaml
|
|
32
|
+
!website/docker-compose.yml
|
|
33
|
+
# Dev-only (not for public repo)
|
|
34
|
+
rl-pipeline-fix.md
|
|
35
|
+
tools/*
|
|
36
|
+
!tools/training/
|
|
37
|
+
!tools/monitoring/
|
|
38
|
+
tools/monitoring/*
|
|
39
|
+
!tools/monitoring/grafana/
|
|
40
|
+
tools/training/checkpoints/
|
|
41
|
+
tools/training/data/
|
|
42
|
+
!tools/eval/
|
|
43
|
+
tools/eval/data/
|
|
44
|
+
!tools/monitoring/
|
|
45
|
+
docs/
|
|
46
|
+
CLAUDE.md
|
|
47
|
+
*.spec
|
|
48
|
+
venv/
|
|
49
|
+
.venv/
|
|
50
|
+
.venv_*/
|
|
51
|
+
test_env/
|
|
52
|
+
# BepInEx plugin build artifacts
|
|
53
|
+
bepinex-plugin/**/bin/
|
|
54
|
+
bepinex-plugin/**/obj/
|
|
55
|
+
.DS_Store
|
|
56
|
+
stage0v2_31b_train.log
|
|
57
|
+
*_train.log
|
|
58
|
+
models/
|
|
59
|
+
|
|
60
|
+
# Dev-machine scratch, deliberately untracked (2026-07-27):
|
|
61
|
+
# launch.sh — hardcodes the old WSL path /home/joshu/repos/mtgacoach
|
|
62
|
+
# run_update.py — one-shot regex migration that REWRITES src/arenamcp/server.py
|
|
63
|
+
# in place; its edits are already merged. Keeping it runnable
|
|
64
|
+
# in the repo is a footgun, not history.
|
|
65
|
+
launch.sh
|
|
66
|
+
run_update.py
|
|
67
|
+
|
|
68
|
+
# Local grading worksheet (contains replay-derived game states; not for the public repo)
|
|
69
|
+
tripwire_review_v2.md
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Pre-commit hooks — install with: pre-commit install
|
|
2
|
+
repos:
|
|
3
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
4
|
+
rev: v4.6.0
|
|
5
|
+
hooks:
|
|
6
|
+
- id: trailing-whitespace
|
|
7
|
+
- id: end-of-file-fixer
|
|
8
|
+
- id: check-yaml
|
|
9
|
+
- id: check-toml
|
|
10
|
+
- id: check-added-large-files
|
|
11
|
+
args: ["--maxkb=500"]
|
|
12
|
+
- id: mixed-line-ending
|
|
13
|
+
args: ["--fix=lf"]
|
|
14
|
+
|
|
15
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
16
|
+
rev: v0.15.22
|
|
17
|
+
hooks:
|
|
18
|
+
- id: ruff
|
|
19
|
+
args: [--fix]
|
|
20
|
+
- id: ruff-format
|
|
21
|
+
|
|
22
|
+
# mypy is advisory-only until the baseline is cleaned up module-by-module.
|
|
23
|
+
# Enable locally with: pre-commit run mypy --all-files
|
|
24
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
25
|
+
rev: v1.11.2
|
|
26
|
+
hooks:
|
|
27
|
+
- id: mypy
|
|
28
|
+
pass_filenames: false
|
|
29
|
+
args: [--config-file=pyproject.toml]
|
|
30
|
+
# Not wired to block commits yet — run manually.
|
|
31
|
+
stages: [manual]
|
arenamcp-2.8.0/AGENTS.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# ArenaMCP — Agent Guidance
|
|
2
|
+
|
|
3
|
+
## Project
|
|
4
|
+
Real-time AI coaching for MTG Arena with in-game overlay (BepInEx-driven ground-truth card positions).
|
|
5
|
+
Python package `arenamcp` under `src/arenamcp/`, desktop PySide6 GUI at `src/arenamcp/desktop/`, BepInEx C# plugin at `bepinex-plugin/MtgaCoachBridge/`.
|
|
6
|
+
|
|
7
|
+
## Key Architecture
|
|
8
|
+
- **`launcher.py`** — internal TUI runtime launcher (subprocess-based, restarts on exit code 42)
|
|
9
|
+
- **`windows_integration.py`** — Windows install/repair helpers (stdlib-only)
|
|
10
|
+
- **`src/arenamcp/desktop/app.py`** — PySide6 desktop app entrypoint (main entry for users)
|
|
11
|
+
- **`src/arenamcp/server.py`** — FastMCP server bridging MTGA logs to LLM
|
|
12
|
+
- **`src/arenamcp/coach.py`** — Coach engine with pluggable LLM backends
|
|
13
|
+
- **`src/arenamcp/standalone.py`** — TUI/"standalone" client (voice + MCP client)
|
|
14
|
+
- **`src/arenamcp/autopilot.py`** — AI autoplay engine
|
|
15
|
+
- **`tests/`** — pytest test suite (600+ tests)
|
|
16
|
+
|
|
17
|
+
## Sister Repository: MageZero RL Training (`~/repos/magezero`)
|
|
18
|
+
`mtgacoach` is paired with **`magezero`**, an AlphaZero-style MCTS reinforcement learning engine running inside an instrumented XMage simulator on `blackwell` (`10.0.0.10`).
|
|
19
|
+
- **Role Split**: `mtgacoach` handles live MTG Arena coaching, GRE state extraction, and HUD overlay. `magezero` trains deck-specific policy/value neural networks via distributed self-play.
|
|
20
|
+
- **Canonical RL Docs**: For RL architecture, hardware topology (R9700 vs RTX 6000s), live training status, and strategy, refer directly to `~/repos/magezero/AGENTS.md` and `~/repos/magezero/docs/PLAN_OF_RECORD.md`.
|
|
21
|
+
- **Telemetry Command**: Inspect the live training run on blackwell via:
|
|
22
|
+
```bash
|
|
23
|
+
ssh joshu@10.0.0.10 'python3 -c "import json, pathlib; runs=sorted(pathlib.Path(\"/home/joshu/repos/magezero/runs\").glob(\"*/run.json\")); d=json.loads(runs[-1].read_text()); print(f\"Run {runs[-1].parent.name} | Gen {d.get(\"current_gen\")} | Stage: {d.get(\"stage\")}\")"'
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Developer Commands
|
|
27
|
+
```bash
|
|
28
|
+
# Install (editable, with all extras)
|
|
29
|
+
pip install -e .[dev,full]
|
|
30
|
+
|
|
31
|
+
# Run tests (isolated log file via ARENAMCP_LOG_FILE env var)
|
|
32
|
+
pytest tests -q
|
|
33
|
+
|
|
34
|
+
# Run diagnostics
|
|
35
|
+
python -m arenamcp.diagnose
|
|
36
|
+
|
|
37
|
+
# Launch desktop app (Linux dev)
|
|
38
|
+
PYTHONPATH=src python -m arenamcp.desktop
|
|
39
|
+
|
|
40
|
+
# Launch standalone TUI
|
|
41
|
+
python -m arenamcp.standalone --backend online
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Local venvs (macOS dev machine)
|
|
45
|
+
- `.venv_mac_311/` — Python 3.11, the working macOS venv (pip, pytest, editable arenamcp). Use this on mac.
|
|
46
|
+
- `.venv/` — Linux/WSL-era venv; pip shebang broken on macOS (points at old ArenaMCP path).
|
|
47
|
+
- Deleted 2026-07-22: `.venv_mac/`, `test_env/` (Python 3.9 — below requires-python >=3.10).
|
|
48
|
+
|
|
49
|
+
## Tooling (added 2026-07-22)
|
|
50
|
+
- **ruff** (lint + format) and **mypy** (advisory) — configs in `pyproject.toml`.
|
|
51
|
+
- **pre-commit** — `.pre-commit-config.yaml`; `pre-commit install` to enable.
|
|
52
|
+
- **CI** — `.github/workflows/tests.yml` runs ruff + pytest on push/PR (installer.yml unchanged).
|
|
53
|
+
- Version single-sourced in `src/arenamcp/__init__.py` (`__version__`); pyproject reads it via hatch dynamic versioning.
|
|
54
|
+
|
|
55
|
+
## BepInEx C# Plugin (Linux dev)
|
|
56
|
+
- **Do NOT** use Wine's `csc` — too old for C# 9.0.
|
|
57
|
+
- Use `dotnet` (`.NET 10 SDK` installed).
|
|
58
|
+
- Override `MtgaDir` for Flatpak Steam:
|
|
59
|
+
```bash
|
|
60
|
+
cd bepinex-plugin/MtgaCoachBridge
|
|
61
|
+
dotnet build -p:MtgaDir="/home/joshu/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common/MTGA"
|
|
62
|
+
```
|
|
63
|
+
- Deploy: copy `bin/Debug/net472/MtgaCoachBridge.dll` to MTGA's `BepInEx/plugins/`.
|
|
64
|
+
|
|
65
|
+
## Testing Quirks
|
|
66
|
+
- `conftest.py` redirects `ARENAMCP_LOG_FILE` to `/tmp/arenamcp-pytest.log` so test noise doesn't pollute `~/.arenamcp/standalone.log`.
|
|
67
|
+
- No linter/formatter config in `pyproject.toml` (only pytest dependency). No pre-commit, no typechecker configured.
|
|
68
|
+
- CI only builds Windows installer via GitHub Actions (`.github/workflows/installer.yml`).
|
|
69
|
+
|
|
70
|
+
## Packaging
|
|
71
|
+
- **`hatchling`** build backend, single package `src/arenamcp`
|
|
72
|
+
- GUI entrypoint: `mtgacoach-desktop = "arenamcp.desktop.app:main"`
|
|
73
|
+
- Installer: Inno Setup script at `installer/mtgacoach.iss`, built only on `windows-latest` runner (tag push `v*` or `workflow_dispatch`).
|
|
74
|
+
|
|
75
|
+
## Log Locations (Windows)
|
|
76
|
+
| Log | Path |
|
|
77
|
+
|-----|------|
|
|
78
|
+
| Desktop UI | `%LOCALAPPDATA%\mtgacoach\desktop.log` |
|
|
79
|
+
| Launcher | `%LOCALAPPDATA%\mtgacoach\desktop-launch.log` |
|
|
80
|
+
| Coach runtime | `%USERPROFILE%\.arenamcp\standalone.log` |
|
|
81
|
+
| Bug reports | `%USERPROFILE%\.arenamcp\bug_reports\bug_*.json` |
|
|
82
|
+
| BepInEx | `<MTGA>\BepInEx\LogOutput.log` |
|
|
83
|
+
|
|
84
|
+
## Development Flow
|
|
85
|
+
- Edits under `src/arenamcp/` take effect on next launch (no C# rebuild needed).
|
|
86
|
+
- `launch.bat` is the canonical Windows entrypoint for repo/manual installs.
|
|
87
|
+
- The coaching engine runs as a subprocess over a JSON pipe protocol (separate from the UI process).
|
arenamcp-2.8.0/DEV.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Development Workflow
|
|
2
|
+
|
|
3
|
+
Use exactly one desktop app during development: the PySide6 app in this repo.
|
|
4
|
+
|
|
5
|
+
## One-Time Setup
|
|
6
|
+
|
|
7
|
+
Run this command on Windows:
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe -m pip install -e Z:\mtgacoach[desktop]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`pip install -e` is important: the desktop app runs directly from the repo source tree.
|
|
14
|
+
`[desktop]` now includes the PySide app plus Kokoro desktop-worker dependencies.
|
|
15
|
+
|
|
16
|
+
This repo already contains a Linux `.venv` for WSL work. Do not try to use `Z:\mtgacoach\.venv` as the Windows launch environment.
|
|
17
|
+
|
|
18
|
+
## Launch
|
|
19
|
+
|
|
20
|
+
Use exactly one launch target:
|
|
21
|
+
|
|
22
|
+
```powershell
|
|
23
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\pythonw.exe Z:\mtgacoach\scripts\launch_desktop.py
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Recommended shortcut target:
|
|
27
|
+
|
|
28
|
+
- `C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\pythonw.exe`
|
|
29
|
+
|
|
30
|
+
Recommended shortcut arguments:
|
|
31
|
+
|
|
32
|
+
- `Z:\mtgacoach\scripts\launch_desktop.py`
|
|
33
|
+
|
|
34
|
+
Recommended shortcut "Start in":
|
|
35
|
+
|
|
36
|
+
- `Z:\mtgacoach`
|
|
37
|
+
|
|
38
|
+
## What Updates On Next Launch
|
|
39
|
+
|
|
40
|
+
- Any edit under `src\arenamcp\` takes effect on the next app launch.
|
|
41
|
+
- Any edit under `src\arenamcp\desktop\` takes effect on the next app launch.
|
|
42
|
+
- No C# rebuild is part of the normal dev loop anymore.
|
|
43
|
+
- Launch does not depend on the package being importable from an editable install; the launcher script adds `src\` directly.
|
|
44
|
+
|
|
45
|
+
If you change Python dependencies or entrypoints, rerun:
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe -m pip install -e Z:\mtgacoach[desktop]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Do Not Use During Development
|
|
52
|
+
|
|
53
|
+
- `C:\Users\Public\Desktop\mtgacoach.lnk`
|
|
54
|
+
- `C:\Program Files\mtgacoach\...`
|
|
55
|
+
- `mtgacoach-dev.lnk`
|
|
56
|
+
|
|
57
|
+
Those are no longer part of the source-iteration workflow.
|
|
58
|
+
|
|
59
|
+
## Useful Commands
|
|
60
|
+
|
|
61
|
+
Launch from a terminal without the GUI script wrapper:
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe -m arenamcp.desktop
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Run tests:
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe -m pytest Z:\mtgacoach\tests -q
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Logs
|
|
74
|
+
|
|
75
|
+
- Desktop UI log: `%LOCALAPPDATA%\mtgacoach\desktop.log`
|
|
76
|
+
- Desktop launcher log: `%LOCALAPPDATA%\mtgacoach\desktop-launch.log`
|
|
77
|
+
- Coach runtime log: `%USERPROFILE%\.arenamcp\standalone.log`
|
|
78
|
+
- Saved bug reports: `%USERPROFILE%\.arenamcp\bug_reports\bug_*.json`
|
|
79
|
+
- BepInEx log: `<MTGA>\BepInEx\LogOutput.log`
|
|
80
|
+
|
|
81
|
+
## Notes
|
|
82
|
+
|
|
83
|
+
- The PySide6 app is the full desktop app now: coach UI plus repair/install flows.
|
|
84
|
+
- The coaching engine still runs as a subprocess internally over the existing JSON pipe protocol. That separation is intentional and keeps the UI responsive while preserving the current backend seam.
|
|
85
|
+
- Customer releases come from the packaged PySide installer built by `installer\build-installer.ps1`.
|
arenamcp-2.8.0/GEMINI.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# GEMINI.md
|
|
2
|
+
|
|
3
|
+
## Project Summary
|
|
4
|
+
|
|
5
|
+
`mtgacoach` (`arenamcp`) is an MTGA coaching project with:
|
|
6
|
+
- **Python Core (`src/arenamcp/`)**: Headless coaching engine driving the pipeline.
|
|
7
|
+
- **Desktop UI (`src/arenamcp/desktop/`)**: PySide6-based frontend providing the dashboard, coaching log, repair tools, and transparent, click-through HUD overlay.
|
|
8
|
+
- **BepInEx Plugin (`bepinex-plugin/MtgaCoachBridge/`)**: C# plugin injected into MTGA for direct GRE state access, action submission, and automation.
|
|
9
|
+
- **Proxy Server (`website/`)**: FastAPI gateway at `api.mtgacoach.com` routing subscriber LLM requests, tracking usage, and providing an eval dashboard.
|
|
10
|
+
- **LLM Evaluation Harness (`tools/eval/`)**: Harness for scoring local model quality (mulligans, turn-actions, replays) using real play prompts.
|
|
11
|
+
- **Sister RL Engine (`~/repos/magezero/`)**: Independent AlphaZero-style MCTS self-play training pipeline running in XMage on `blackwell` (`10.0.0.10`). Refer to `~/repos/magezero/AGENTS.md` and `~/repos/magezero/docs/PLAN_OF_RECORD.md` for RL telemetry and status.
|
|
12
|
+
|
|
13
|
+
## Core Direction & Architecture
|
|
14
|
+
|
|
15
|
+
- **GRE Bridge is Primary**: Real-time game state tracking and action submissions run through the direct Unity GRE named pipe (`\\.\pipe\mtgacoach_bridge_v2`). Python acts as the named pipe server; BepInEx is the client.
|
|
16
|
+
- **Log Parsing as Fallback**: `Player.log` is parsed via a log watcher only as a fallback and for out-of-match/metadata diagnostics.
|
|
17
|
+
- **File System Separation**: Installed files live read-only under `Program Files\mtgacoach`, while mutable runtime files (venv, settings, logs) belong under `%LOCALAPPDATA%\mtgacoach` and `%USERPROFILE%\.arenamcp`.
|
|
18
|
+
- **Local LLM Default**: Default local backend is **vLLM** (`http://localhost:8000/v1`) running `google/gemma-4-E2B-it` (aliased as `gemma4:e2b`), with fallback to Ollama (`localhost:11434`) or LM Studio.
|
|
19
|
+
|
|
20
|
+
## LLM Evaluation Harness (`tools/eval/`)
|
|
21
|
+
|
|
22
|
+
- Runs idempotent evaluation pipelines using captured prompts (`prompts.jsonl`).
|
|
23
|
+
- **Replay Scorer (`tools/eval/replay/`)**: Replays prompts through backends (`run.py`) and scores them against judge models on **contested decisions** (decisions where the player had a choice, to prevent easy moves from inflating match rate).
|
|
24
|
+
- **Mulligan Scorer**: Uses balanced accuracy (`balanced_higher_wr_rate`) to avoid keep-rate bias. Skips buckets within `MARGIN_THRESHOLD=0.05`.
|
|
25
|
+
- **Turn-action Scorer**: Uses Mean Jaccard (set overlap) as the headline metric.
|
|
26
|
+
- Supports WSL paths to allow running WSL evaluators against Windows MTGA paths.
|
|
27
|
+
|
|
28
|
+
## Installer & Repair UX
|
|
29
|
+
|
|
30
|
+
- Prefer a **small installer** built by `installer/build-installer.ps1` that packages the application and downloads/creates the venv post-install.
|
|
31
|
+
- The repair UI must offer explicit user-visible actions for:
|
|
32
|
+
- `Create venv`
|
|
33
|
+
- `Setup environment`
|
|
34
|
+
- `Install BepInEx`
|
|
35
|
+
- `Install Plugin`
|
|
36
|
+
- Bridge repair / refresh actions
|
|
37
|
+
|
|
38
|
+
## Release Rules
|
|
39
|
+
|
|
40
|
+
When revving a release (currently version `2.7.3`):
|
|
41
|
+
1. Bump version in:
|
|
42
|
+
- `pyproject.toml`
|
|
43
|
+
- `src/arenamcp/__init__.py`
|
|
44
|
+
- `installer/mtgacoach.iss`
|
|
45
|
+
2. Commit changes.
|
|
46
|
+
3. Tag `vX.Y.Z`.
|
|
47
|
+
4. Build the installer (`build-installer.ps1`) and verify the output at `dist/installer/mtgacoach-Setup.exe`.
|
|
48
|
+
5. Push master and tag.
|
|
49
|
+
6. Create/update the GitHub release and upload `mtgacoach-Setup.exe`.
|
|
50
|
+
|
|
51
|
+
## Common Commands
|
|
52
|
+
|
|
53
|
+
### Setup & Run
|
|
54
|
+
```powershell
|
|
55
|
+
# Editable dev install (Windows)
|
|
56
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe -m pip install -e Z:\mtgacoach[desktop]
|
|
57
|
+
|
|
58
|
+
# Run PySide6 app from source
|
|
59
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe -m arenamcp.desktop
|
|
60
|
+
|
|
61
|
+
# Launch app using wrapper script
|
|
62
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\pythonw.exe Z:\mtgacoach\scripts\launch_desktop.py
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Build & Test
|
|
66
|
+
```powershell
|
|
67
|
+
# Run regression tests
|
|
68
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe -m pytest Z:\mtgacoach\tests -q
|
|
69
|
+
|
|
70
|
+
# Build BepInEx plugin DLL (C#)
|
|
71
|
+
cd bepinex-plugin/MtgaCoachBridge && dotnet build -c Release
|
|
72
|
+
|
|
73
|
+
# Build Windows installer from WSL
|
|
74
|
+
p=$(wslpath -w /home/joshu/repos/mtgacoach/installer) && powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "\$p='${p}'; Set-Location -LiteralPath \$p; .\build-installer.ps1"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Verification & Eval
|
|
78
|
+
```powershell
|
|
79
|
+
# Verify local vLLM endpoint
|
|
80
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe tools/verify_vllm.py
|
|
81
|
+
|
|
82
|
+
# Run replay evaluation harness
|
|
83
|
+
C:\Users\joshu\AppData\Local\mtgacoach\venv\Scripts\python.exe tools/eval/replay/run.py
|
|
84
|
+
```
|
|
85
|
+
## Repository Directory & File Map
|
|
86
|
+
|
|
87
|
+
### Top-Level Layout
|
|
88
|
+
* **`src/`**: The core Python codebase (`arenamcp`). This is the heart of the backend coaching loop, logs, game-state logic, Named Pipe GRE bridge server, and PySide6 desktop UI.
|
|
89
|
+
* **`bepinex-plugin/`**: The C# Unity plugin injected into Magic: The Gathering Arena. It intercepts internal game states and acts as a Named Pipe client connecting directly to Python.
|
|
90
|
+
* **`website/`**: A FastAPI application running on `api.mtgacoach.com` (under Synology/Docker) that validates licenses, routes LLM requests to the LiteLLM gateway (self-hosted models only; the legacy Azure/OpenAI path is decommissioned), and serves the admin evaluation dashboard.
|
|
91
|
+
* **`tools/`**: Diagnostic scripts, vLLM verification tools, and the comprehensive evaluation harness (`tools/eval/`) for measuring LLM output quality.
|
|
92
|
+
* **`installer/`**: Inno Setup script (`mtgacoach.iss`) and build automation scripts (`build-installer.ps1`) to generate the lightweight Windows setup executable.
|
|
93
|
+
* **`dist/`** *(Generated)*: Where release builds of the app and final installer packages are staged.
|
|
94
|
+
* **`venv/`** / **`.venv/`** *(Gitignored)*: Local Python virtual environments used during WSL/Windows development.
|
|
95
|
+
* **`.tools/`** / **`.vscode/`** *(Gitignored)*: IDE configuration and local development helper scripts.
|
|
96
|
+
|
|
97
|
+
### Python Coaching Engine ([src/arenamcp/](file:///Z:/mtgacoach/src/arenamcp))
|
|
98
|
+
|
|
99
|
+
#### Communication & Protocols
|
|
100
|
+
* [pipe_adapter.py](file:///Z:/mtgacoach/src/arenamcp/pipe_adapter.py) — Establishes the JSON-over-stdio protocol used by the headless coaching subprocess to communicate back to the PySide6 desktop frontend.
|
|
101
|
+
* [gre_bridge.py](file:///Z:/mtgacoach/src/arenamcp/gre_bridge.py) — Runs a local Named Pipe server (`\\.\pipe\mtgacoach_bridge_v2`) to exchange game snapshots and execute automation actions with the BepInEx Unity plugin.
|
|
102
|
+
* [gre_serializer.py](file:///Z:/mtgacoach/src/arenamcp/gre_serializer.py) — Protobuf JSON translator for GRE events.
|
|
103
|
+
* [gre_action_matcher.py](file:///Z:/mtgacoach/src/arenamcp/gre_action_matcher.py) — Maps high-level decisions from the action planner to low-level GRE action objects.
|
|
104
|
+
* [parser.py](file:///Z:/mtgacoach/src/arenamcp/parser.py) & [watcher.py](file:///Z:/mtgacoach/src/arenamcp/watcher.py) — File watcher and parser for `Player.log` acting as a fallback data source.
|
|
105
|
+
|
|
106
|
+
#### State & Decision Engine
|
|
107
|
+
* [gamestate.py](file:///Z:/mtgacoach/src/arenamcp/gamestate.py) — Main game state management. Processes direct GRE bridge protobuf messages and log parsing.
|
|
108
|
+
* [coach.py](file:///Z:/mtgacoach/src/arenamcp/coach.py) — Prompt building, LLM querying, advice post-processing, and fallback deterministic scoring logic.
|
|
109
|
+
* [action_planner.py](file:///Z:/mtgacoach/src/arenamcp/action_planner.py) — Autonomous gameplay planning using LLM-generated actions.
|
|
110
|
+
* [autopilot.py](file:///Z:/mtgacoach/src/arenamcp/autopilot.py) — Core executor for autonomous play, utilizing GRE bridge API and OS level inputs.
|
|
111
|
+
* [combat_solver.py](file:///Z:/mtgacoach/src/arenamcp/combat_solver.py) — Solves complex combat math for planning.
|
|
112
|
+
* [standalone.py](file:///Z:/mtgacoach/src/arenamcp/standalone.py) — Entry point for headless coaching loop, managing trigger states.
|
|
113
|
+
|
|
114
|
+
#### Database & External APIs
|
|
115
|
+
* [scryfall.py](file:///Z:/mtgacoach/src/arenamcp/scryfall.py) — Scryfall REST API client with local disk cache.
|
|
116
|
+
* [draftstats.py](file:///Z:/mtgacoach/src/arenamcp/draftstats.py) & [draft_eval.py](file:///Z:/mtgacoach/src/arenamcp/draft_eval.py) — Queries and processes 17lands data to evaluate draft options.
|
|
117
|
+
* [mtgadb.py](file:///Z:/mtgacoach/src/arenamcp/mtgadb.py) & [mtgjson.py](file:///Z:/mtgacoach/src/arenamcp/mtgjson.py) — Integrates local card lookup SQLite databases.
|
|
118
|
+
|
|
119
|
+
#### Interaction & Desktop Integration
|
|
120
|
+
* [input_controller.py](file:///Z:/mtgacoach/src/arenamcp/input_controller.py) — Coordinates direct OS clicks and key input automation.
|
|
121
|
+
* [screen_mapper.py](file:///Z:/mtgacoach/src/arenamcp/screen_mapper.py) — Calculates positions on screen for card/button interactions.
|
|
122
|
+
* [vision_mapper.py](file:///Z:/mtgacoach/src/arenamcp/vision_mapper.py) — VLM-based pixel-level fallback coordinate resolver.
|
|
123
|
+
* [tts.py](file:///Z:/mtgacoach/src/arenamcp/tts.py) & [transcription.py](file:///Z:/mtgacoach/src/arenamcp/transcription.py) — Text-to-Speech synthesis and transcription integration.
|
|
124
|
+
|
|
125
|
+
### Desktop UI Subsystem ([src/arenamcp/desktop/](file:///Z:/mtgacoach/src/arenamcp/desktop))
|
|
126
|
+
* [app.py](file:///Z:/mtgacoach/src/arenamcp/desktop/app.py) — PySide6 application runtime initialization.
|
|
127
|
+
* [main_window.py](file:///Z:/mtgacoach/src/arenamcp/desktop/main_window.py) — Main workspace window and tab shell.
|
|
128
|
+
* [coach_tab.py](file:///Z:/mtgacoach/src/arenamcp/desktop/coach_tab.py) — Central control panel for voice settings, engine logs, and session controls.
|
|
129
|
+
* [repair_tab.py](file:///Z:/mtgacoach/src/arenamcp/desktop/repair_tab.py) — Self-healing diagnostic interface (venv setup, environment settings, BepInEx installation, and bridge validation).
|
|
130
|
+
* [hud.py](file:///Z:/mtgacoach/src/arenamcp/desktop/hud.py) & [card_overlay.py](file:///Z:/mtgacoach/src/arenamcp/desktop/card_overlay.py) — Transparent click-through overlay window displaying draft reviews directly on top of MTGA.
|
|
131
|
+
* [coach_process.py](file:///Z:/mtgacoach/src/arenamcp/desktop/coach_process.py) — Manages standard subprocess pipes to start/stop the standalone backend process.
|
|
132
|
+
|
|
133
|
+
### Unity C# Plugin ([bepinex-plugin/MtgaCoachBridge/](file:///Z:/mtgacoach/bepinex-plugin/MtgaCoachBridge))
|
|
134
|
+
* [Plugin.cs](file:///Z:/mtgacoach/bepinex-plugin/MtgaCoachBridge/Plugin.cs) — Injected DLL logic. Injects into MTGA Unity lifecycle, handles connection to local Named Pipe (`\\.\pipe\mtgacoach_bridge_v2`), and executes marshaled main-thread queries/actions.
|
|
135
|
+
* [BotBattleBridge.cs](file:///Z:/mtgacoach/bepinex-plugin/MtgaCoachBridge/BotBattleBridge.cs) — Intercepts and logs bot match statistics and triggers.
|
|
136
|
+
|
|
137
|
+
### Proxy Server Backend ([website/](file:///Z:/mtgacoach/website))
|
|
138
|
+
* [app.py](file:///Z:/mtgacoach/website/app.py) — FastAPI server routing LLM requests, validating client keys, and exposing admin portals.
|
|
139
|
+
* [providers.py](file:///Z:/mtgacoach/website/providers.py) — Provider wrappers with priority-based route fallbacks and backoff logic.
|
|
140
|
+
* [db.py](file:///Z:/mtgacoach/website/db.py) — SQLite wrapper tracking client license tokens and server metrics.
|
|
141
|
+
* [templates/admin.html](file:///Z:/mtgacoach/website/templates/admin.html) — Cloud admin evaluation dashboard, displaying real-time latencies, charts, and metrics tables.
|
|
142
|
+
|
|
143
|
+
### Evaluation Harness ([tools/eval/](file:///Z:/mtgacoach/tools/eval))
|
|
144
|
+
* [run.py](file:///Z:/mtgacoach/tools/eval/run.py) & [judge.py](file:///Z:/mtgacoach/tools/eval/judge.py) — Replays prompt sets through custom backends and uses a self-hosted judge model to grade model output.
|
|
145
|
+
* [report.py](file:///Z:/mtgacoach/tools/eval/report.py) — Generates accuracy tables and markdown report summaries.
|
|
146
|
+
* [replay/run.py](file:///Z:/mtgacoach/tools/eval/replay/run.py) & [replay/score.py](file:///Z:/mtgacoach/tools/eval/replay/score.py) — Runs and scores model outputs on real-game replay prompts, focusing on contested decisions to filter out easy play bias.
|
|
147
|
+
* [seventeenlands/score_mulligan.py](file:///Z:/mtgacoach/tools/eval/seventeenlands/score_mulligan.py) & [seventeenlands/score_turn_actions.py](file:///Z:/mtgacoach/tools/eval/seventeenlands/score_turn_actions.py) — Scores decisions against 17lands data using balanced accuracy and Jaccard metrics.
|
|
148
|
+
|
|
149
|
+
## Hygiene
|
|
150
|
+
|
|
151
|
+
Do not commit:
|
|
152
|
+
- `.venv/` or `venv/`
|
|
153
|
+
- `.tools/`
|
|
154
|
+
- `bin/` or `obj/`
|
|
155
|
+
- Scratch files (e.g. `.ab` files, `last_match_event.txt`, debug logs)
|
|
156
|
+
- Generated `dist/` or `build/` files
|
|
157
|
+
|
|
158
|
+
`tests/` may be ignored in git by default; use `git add -f tests/...` if you need to add new tests to git.
|