A web-first Commander/EDH deckbuilder with a shared core for CLI, headless, and Docker workflows. It builds curated decks, enforces bracket policies, understands owned cards, and ships a modern FastAPI + HTMX UI.
- **Web UI priority**: All homepage actions map to the sections below.
- **Shared logic**: Web, CLI, and headless runs use the same builder engine and exports.
- **Deterministic outputs**: Random modes respect seeds, include/exclude lists, and bracket rules.
- **Data-aware UX**: Owned library, themes, commanders, diagnostics, and logs live side-by-side.
- [Data, exports, and volumes](#data-exports-and-volumes)
- [Environment variables](#environment-variables)
- [Project layout](#project-layout)
- [Development setup](#development-setup)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License & attribution](#license--attribution)
- [Further reading](#further-reading)
---
## Quick start
Pick the path that fits your setup. All commands target Windows PowerShell.
### Option 1 — Docker Compose (recommended web experience)
```powershell
docker compose up --build --no-deps -d web
```
The Web UI starts on http://localhost:8080. First boot seeds data, refreshes decks, and tags cards automatically (see env defaults in `docker-compose.yml`). Use `docker compose stop web` / `docker compose start web` to pause or resume.
### Option 2 — Docker Hub image
```powershell
docker run --rm -p 8080:8080 `
-v "${PWD}/deck_files:/app/deck_files" `
-v "${PWD}/logs:/app/logs" `
-v "${PWD}/csv_files:/app/csv_files" `
-v "${PWD}/config:/app/config" `
-v "${PWD}/owned_cards:/app/owned_cards" `
mwisnowski/mtg-python-deckbuilder:latest
```
Brings up the same web UI using the prebuilt image. All volumes persist on the host.
- **Quick Build**: One-click automation runs the full workflow with live progress (Creatures → Spells → Lands → Final Touches → Summary). Available in New Deck wizard.
- **Skip Controls**: Granular stage-skipping toggles in New Deck wizard (21 flags: land steps, creature stages, spell categories). Auto-advance without approval prompts.
- Partner mechanics (ENABLE_PARTNER_MECHANICS): Step 2 and the quick-start modal auto-enable partner controls for eligible commanders, show only legal partner/background/Doctor options, and keep previews, warnings, and theme chips in sync.
- Partner suggestions (ENABLE_PARTNER_SUGGESTIONS): ranked chips appear beside the partner selector, recommending popular partner/background/Doctor pairings based on the analytics dataset; selections respect existing partner mode and lock states.
- Partner: pick a second commander from the filtered dropdown labeled “Partner commander”; the background picker clears automatically.
- Partner With: the canonical partner pre-fills and surfaces an opt-out chip so you can keep or swap the suggestion.
- Doctor / Doctor’s Companion: Doctors list legal companions (and vice versa) with role labels, and the opt-out chip mirrors Partner With behavior.
- Background: choose a Background instead of a second commander; partner selectors hide when not applicable.
- Exports (CSV, TXT, compliance JSON, summary JSON) land in `deck_files/` and reuse your chosen deck name when set. CSV/TXT headers now include commander metadata (names, partner mode, colors) so downstream tools can pick up dual-commander context without extra parsing.
- Supplemental themes: add `"additional_themes": ["Theme A", "Theme B"]` plus `"theme_match_mode": "permissive"|"strict"`. Strict mode stops the build when a theme cannot be resolved; permissive keeps going and prints suggestions. Exported configs also include a camelCase alias (`"userThemes"`) and the active catalog version (`"themeCatalogVersion"`); either field name is accepted on import.
- Dual-commander support (feature-flagged): `--secondary-commander` or `--background` (mutually exclusive) can be supplied alongside `--enable-partner-mechanics true` or `ENABLE_PARTNER_MECHANICS=1`; Partner With and Doctor/Doctor’s Companion pairings auto-resolve (respecting opt-outs), dry runs echo the resolved pairing, and JSON configs may include `secondary_commander`, `background`, and `enable_partner_mechanics` keys.
Exports follow a stable naming scheme and include a `.summary.json` sidecar containing deck metadata, resolved themes, combined commander payloads, and lock history.
| `CACHE_CARD_IMAGES` | `0` | Download card images to `card_files/images/` (1=enable, 0=fetch from API on demand). Requires ~3-6 GB. See [Image Caching](docs/IMAGE_CACHING.md). |
Refer to `.env.example` for advanced editorial, taxonomy, and experimentation knobs (`EDITORIAL_*`, `SPLASH_ADAPTIVE`, `WEB_THEME_FILTER_PREWARM`, etc.). Document any newly introduced variables in the README, DOCKER guide, compose files, and `.env.example`.
---
## Project layout
```
code/ FastAPI app, deckbuilding engine, CLI, scripts, and tests
├─ web/ Web UI (FastAPI + Jinja2 + HTMX)
├─ deck_builder/ Core builder logic and services
├─ tagging/ Tag pipelines and utilities
├─ locks/ Card locking utilities
├─ scripts/ Maintenance and editorial tools
├─ tests/ Pytest suite (web, CLI, random, tagging)
Use `tasks.json` entries such as `pytest-fast-random` or `pytest-fast-locks` for quick feedback.
5. Linting and type checks follow `pyproject.toml` / `mypy.ini` defaults. Keep changes minimal and well-typed.
When adding features, favor the web UI first, keep public builder APIs stable, and update documentation (CHANGELOG → RELEASE_NOTES_TEMPLATE → DOCKER → README) in that order.
---
## Troubleshooting
- **Blank page after start**: Visit `/healthz`, check `/logs`, ensure `SHOW_LOGS=1`, and inspect host `logs/` for stack traces.
- **Stale data**: Run Initial Setup or delete `csv_files/.tagging_complete.json` to force reseeding.
- **Owned-only build fails**: Confirm owned files were uploaded correctly and that `owned_cards/` is mounted.
- **Random build stalls**: Lower `RANDOM_MAX_ATTEMPTS`, increase `RANDOM_TIMEOUT_MS`, and verify selected themes exist via `/themes/`.
- **Commander list outdated**: Rerun the commander refresh script or Initial Setup.
---
## Contributing
Pull requests are welcome—follow the conventional commit style, keep diffs focused, add or update tests when behavior changes, and document new env vars or workflows. Review `CONTRIBUTING_EDITORIAL.md` for editorial tooling guidance.
---
## License & attribution
Licensed under the [MIT License](LICENSE). Card data and imagery are provided by [Scryfall](https://scryfall.com); please respect their [API terms](https://scryfall.com/docs/api).
---
## Further reading
- [Web UI deep dive](docs/web_ui_deep_dive.md) – advanced Stage 5 tooling, multi-copy packages, virtualization tips, and diagnostics overlays.
- [Theme catalog advanced guide](docs/theme_catalog_advanced.md) – API endpoints, governance policies, editorial tooling, and validation scripts.