692 Commits
Author SHA1 Message Date
KoalaTrapLord 0923b75d79 Unity U3: Add CardModel.cs with Newtonsoft.Json snake_case mapping (#48)
This class represents a Magic: The Gathering card with various properties such as name, oracle ID, mana cost, and more.
2026-03-18 01:58:24 -04:00
KoalaTrapLord 20172c90b4 Unity U2: Implement all FastAPI endpoint methods in ApiClient.cs (closes #47) 2026-03-18 01:56:33 -04:00
KoalaTrapLord 089c1abc8d Unity: Add ProjectSettings/ProjectVersion.txt for 2022.3 LTS (#46) 2026-03-18 01:53:21 -04:00
KoalaTrapLord 646da59e2a Unity: Add .gitignore for Unity project (Library, Temp, Builds) (#46) 2026-03-18 01:52:29 -04:00
KoalaTrapLord 10a7662d51 Unity: Add Fonts/.gitkeep (#46) 2026-03-18 01:51:38 -04:00
KoalaTrapLord a6171b5180 Unity: Add Textures/.gitkeep (#46) 2026-03-18 01:51:10 -04:00
KoalaTrapLord b09fe4b48b Unity: Add Materials/.gitkeep (#46) 2026-03-18 01:50:46 -04:00
KoalaTrapLord cb8867a808 Unity: Add Prefabs/.gitkeep (#46) 2026-03-18 01:50:23 -04:00
KoalaTrapLord 3d6365cfb4 Unity: Add Scripts/Animation/.gitkeep (#46) 2026-03-18 01:50:00 -04:00
KoalaTrapLord 397d02240e Unity: Add Scripts/UI/.gitkeep (#46) 2026-03-18 01:49:37 -04:00
KoalaTrapLord 0c842b97fd Unity: Add Scripts/Models/.gitkeep (#46) 2026-03-18 01:49:16 -04:00
KoalaTrapLord 7e94b29c6d Unity: Add Assets/Scenes/.gitkeep for folder scaffold (#46)
This file keeps the folder in git
2026-03-18 01:48:49 -04:00
Commander AI Lab Agent fbc3bdb6b5 fix: add _resolve_precon_dir() auto-detection so CFG.precon_dir is not empty
The precon deck list was missing after the monolith refactor because
PRECON_DIR was hardcoded in services/precon_service.py with no CLI arg,
env var, or auto-resolve fallback — unlike forge_jar, forge_dir, etc.

Changes:
- Add precon_dir field to Config class (models/state.py)
- Add --precon-dir CLI arg and PRECON_DIR env var support
- Add _resolve_precon_dir() with project-root, parent-dir, and
  forge_dir-relative detection; creates dir as fallback for downloads
- Refactor precon_service.py to use _get_precon_dir() helper that reads
  CFG.precon_dir at runtime instead of a hardcoded module-level Path
- Update routes/precon.py to use _get_precon_dir() for install endpoints
- Wire _on_startup to resolve precon_dir for uvicorn-direct launches
- Remove unused PRECON_DIR/PRECON_INDEX imports from routes/lab.py
- Audit confirms all other CFG path fields already have fallbacks
2026-03-18 04:56:03 +00:00
KoalaTrapLord a5b9d70f04 Unity U2: Add ApiClient.cs singleton HTTP client for FastAPI backend (Epic #45) 2026-03-18 00:55:40 -04:00
KoalaTrapLord 8103a06992 Unity U1: scaffold unity-client/ folder + README (Epic #45) 2026-03-18 00:53:39 -04:00
ClaudeandClaude Opus 4.6 85df46364a fix: add _resolve_forge_dir() auto-detection so CFG.forge_dir is not empty
Same pattern as the previous _resolve_forge_jar() fix — when --forge-dir
is not passed via CLI or FORGE_DIR env var, auto-detect the Forge
installation directory by:
1. Deriving from the already-resolved forge_jar path (parent of target/)
2. Checking common sibling directories (forge/, forge-repo/)
3. Checking platform user data dirs (~/.forge, ~/Forge, %APPDATA%/Forge)

Also audited all other CFG fields — forge_jar, forge_decks_dir, lab_jar,
port, results_dir all already have proper defaults or auto-resolve
fallbacks. Added Forge Dir, Lab JAR, and Results Dir to startup log
output for better diagnostics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 04:50:23 +00:00
Claude 32f3c9dfa3 fix: add _resolve_forge_jar() auto-detection so CFG.forge_jar is not empty
During the refactor from the monolith into services/, the forge JAR path
had no auto-resolve fallback — unlike lab_jar and forge_decks_dir which
both had resolver functions. When --forge-jar CLI arg and FORGE_JAR env
var are both unset, CFG.forge_jar stayed "" causing POST /api/lab/start
to fail with "Forge JAR not found: ".

Add _resolve_forge_jar() that scans common sibling directories for
forge-gui-desktop-*-jar-with-dependencies.jar (matching the pattern
from start-lab.bat), and wire it as the fallback in main().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 04:44:20 +00:00
ClaudeandClaude Opus 4.6 7bc4aac0aa fix: repair run_batch_subprocess signature and _run_process_blocking state attrs in forge_runner.py
The port of run_batch_subprocess from lab_api_backup.py to
services/forge_runner.py truncated the function signature to 8 params +
**kwargs, but the route handler in routes/lab.py passes 13 positional
arguments, causing TypeError at runtime when POST /api/lab/start fires.

Restore all 13 explicit parameters (policy_style, policy_greedy,
ai_simplified, ai_think_time_ms, max_queue_depth) to match the caller
and pass them as keyword args to build_java_command. Also compute
policy_server from CFG.port and add error handling, matching the
original backup implementation.

Additionally, _run_process_blocking was writing to wrong BatchState
attribute names (state.status, state.games_done, state.games_total,
state.throughput, state.log, state.started_at, state.ended_at) instead
of the correct ones (state.running, state.completed_games,
state.total_games, state.sims_per_sec, state.log_lines, state.elapsed_ms).
This caused the /api/lab/status endpoint to never see progress updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 04:38:40 +00:00
ClaudeandClaude Opus 4.6 70ad16fc79 fix: add missing _get_deepseek_brain and _run_deepseek_batch_thread to forge_runner.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 04:31:14 +00:00
ClaudeandClaude Opus 4.6 6298f83abd fix: correct indentation errors in services/*.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 04:22:17 +00:00
Claude d1422d6f64 fix: correct indentation errors in services/database.py 2026-03-18 04:15:06 +00:00
KoalaTrapLord 4e8a999ebd feat: add Unity/Godot WebSocket server (Phase 1 stub)
- pom.xml: add Java-WebSocket 1.5.6 dependency
- bridge/GameWsServer.java: WS server on ws://localhost:7654
- bridge/GameSession.java: Phase 1 stub game loop with human-input queue
- cli/LabCli.java: add ws-server subcommand via picocli
2026-03-18 00:02:18 -04:00
KoalaTrapLord aa5e381c59 feat: add 4-player batch simulator React page with N-player API endpoint
Adds SimulatorPage at /simulator with 4 deck slot selection, config panel, progress polling, per-seat win rate charts, and stats table. Backend: POST /api/sim/run-n-player endpoint using engine.run_n() for 2-4 player batch sims.
2026-03-17 23:59:48 -04:00
Commander AI LabandClaude Opus 4.6 3f66a8ed15 feat: add 4-player batch simulator React page with N-player API endpoint
- Add POST /api/sim/run-n-player endpoint accepting 2-4 deck IDs for
  N-player batch simulations using the existing engine.run_n() method
- Add _run_sim_thread_n_player tracking per-seat wins and stats
- Create SimulatorPage.tsx with 4 deck selection slots, config row,
  progress bar, results table, CSS bar chart, and per-game logs
- Add simulator types in frontend/src/types/simulator.ts
- Add /simulator route and nav bar to App.tsx

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 03:39:03 +00:00
KoalaTrapLord f4da7674b6 feat: React + TypeScript frontend migration (all 12 phases)
Complete migration of the Commander AI Lab GUI from vanilla JS to React + TypeScript + Vite + Tailwind.

Phases implemented:
- Phase 1: Vite + React-TS scaffold with proxy config
- Phase 2: TypeScript type definitions (game.ts, constants.ts)
- Phase 3: useGameSocket hook + gameReducer
- Phase 4: Core components (PhaseBar, PlayerZone, CardChip, Board)
- Phase 5: NarrationPanel with auto-scroll
- Phase 6: MoveBar + HandCard
- Phase 7: GameOverOverlay
- Phase 8: App routing + GamePage assembly
- Phase 9: Lobby UI (LobbyPage, RoomPage, useLobbySock, spectator mode)
- Phase 10: Tailwind colour tokens
- Phase 11: Build integration + CI + README
- Phase 12: Test suite (26 tests, all passing)
2026-03-17 22:58:54 -04:00
Claude 0b623ec39e feat: add lobby UI, build integration, and test suite (Phases 9, 11, 12)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 02:56:16 +00:00
ClaudeandClaude Opus 4.6 d489f84825 feat: implement game UI components, WebSocket hook, routing (Phases 3-8)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 02:43:43 +00:00
ClaudeandClaude Opus 4.6 d1bed9ac20 feat: scaffold React+TS frontend with types and Tailwind tokens (Phases 1, 2, 10)
Phase 1 — Project Scaffold:
- Vite + React-TS project in frontend/ with Tailwind v3, PostCSS, Autoprefixer
- clsx and react-router-dom installed
- Vite proxy configured for /api and /ws to localhost:8000
- Tailwind directives in src/index.css
- Makefile targets: frontend-dev, frontend-build
- app.py updated to serve frontend/dist/ with SPA catch-all fallback

Phase 2 — Type Definitions:
- TypeScript types in frontend/src/types/game.ts (Phase, Card, Player,
  GameState, WsIncoming, NarrationLine)
- Constants in frontend/src/constants.ts (SEAT_COLOURS, PHASES)

Phase 10 — Tailwind Colour Tokens:
- Custom color tokens for bg, accent, life, seat, card color groups
- Additional tokens from index.html audit: border, phase, btn, text, highlight
- Custom pulse animation keyframe

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 02:35:50 +00:00
KoalaTrapLord 3f38a9885f Slim install script from 3.2MB to git clone approach (~8KB) - closes #31
This script installs the Commander AI Lab environment by checking prerequisites, cloning the repository, and installing dependencies.
2026-03-17 16:20:19 -04:00
KoalaTrapLord 940836db7e Add GitHub Actions CI workflow (lint + test on push) - closes #33 2026-03-17 16:18:50 -04:00
KoalaTrapLord fd74f157e8 Phase 4: Slim lab_api.py to thin main() - closes #25
Refactor lab_api.py to streamline imports, improve logging, and enhance argument parsing.
2026-03-17 16:17:53 -04:00
KoalaTrapLord 179a53c0af Implement Moxfield deck source adapter (closes #35) 2026-03-17 15:59:10 -04:00
KoalaTrapLord 554b166787 Phase 2d/2e/2f: Extract forge_runner, precon_service, import_service/helpers into services/ 2026-03-17 15:22:19 -04:00
KoalaTrapLord 874561f423 Phase 2c: Extract card analysis to services/card_analysis.py (#12) 2026-03-17 05:14:35 -04:00
KoalaTrapLord c7309d1ace Phase 2b: Extract deck service to services/deck_service.py (#11) 2026-03-17 05:05:52 -04:00
KoalaTrapLord 5aee93dfae Phase 1c: Extract datPhase 2a: Extract Scryfall client to services/scryfall.py (#10)abase service to services/database.py (#9) 2026-03-17 04:54:36 -04:00
KoalaTrapLord e14a6f9500 Phase 1c: Extract database service to services/database.py (#9) 2026-03-17 04:40:44 -04:00
KoalaTrapLord 7baae153ae Phase 1b: Extract Config, BatchState, AI_PROFILES into models/state.py (#8) 2026-03-17 01:57:22 -04:00
KoalaTrapLord eadf54c670 Phase 1a: Extract Pydantic models into models/requests.py + models/responses.py (#7) 2026-03-17 01:45:57 -04:00
KoalaTrapLord 312d13949d feat: extract ML endpoints into routes/ml.py (#36)
Moved all 15 /api/ml/* endpoints, 4 state dicts, and 3 background
pipeline functions from lab_api.py into routes/ml.py. Wired via
app.include_router(ml_router) in lab_api.py.
2026-03-17 00:41:31 -04:00
KoalaTrapLord 192c307ca7 refactor(#42): deduplicate sim thread functions in deepseek.py 2026-03-17 00:20:51 -04:00
KoalaTrapLord 5cb6e6ce81 refactor(#41): remove duplicate _get_deepseek_brain from deepseek.py, import from shared 2026-03-17 00:08:04 -04:00
KoalaTrapLord 01af4d7bcf cleanup(#38): delete stale ROUTES_WIRING.md
This doc referenced the old routes._wire autoload pattern and only listed 5 routers. The project now uses 9 direct include_router() calls. Closes #38.
2026-03-17 00:05:19 -04:00
KoalaTrapLord 301b9d38c8 fix(#40): use Path().parent.parent for correct src/ resolution in routes/deepseek.py 2026-03-17 00:02:22 -04:00
KoalaTrapLord 09b0708c4d fix(models): commander_tax int→dict to match engine per-commander tax tracking 2026-03-16 23:58:07 -04:00
KoalaTrapLord 1121e1cb26 feat: add commander_bonus weight to score_card()
Commanders get +5.0 priority in AI spell selection, making the
AI prioritize casting its commander when affordable.
2026-03-17 03:38:14 +00:00
KoalaTrapLord 4bade21220 feat: route commander deaths to command zone instead of graveyard
Added _send_to_graveyard() helper that checks card.is_commander
and routes to command_zone (resetting tapped/turn_played) or
graveyard. Applied to all 4 death paths: removal, board wipe,
blocker death, and attacker death in combat.
2026-03-17 03:36:36 +00:00
KoalaTrapLord 46421fe8c4 feat: add commander casting from command zone with tax tracking
Second pass in _play_spells() checks command_zone for castable
commanders, applies commander_tax, taps lands, places on
battlefield, and increments tax by 2 for subsequent casts.
2026-03-17 03:34:25 +00:00
KoalaTrapLord da5e9bd74f feat: set is_commander during deck loading, place in command_zone
- Add commander_names param to run(), run_n(), _create_state()
- Commander card flagged is_commander=True and placed in
  player.command_zone instead of shuffled into library/hand
- Only first matching card is extracted (handles singleton rule)
- Backward compatible: commander_names defaults to None
2026-03-17 03:31:35 +00:00
KoalaTrapLord 019a710acd feat: add command_zone and commander_tax to Player dataclass
Adds command_zone (list[Card]) and commander_tax (int, +2 per cast)
to the base Player model so the headless engine can track commander
zone and tax natively without requiring CommanderPlayer wrappers.
2026-03-17 03:18:06 +00:00