draftomen 0.3.1__tar.gz → 0.4.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.
- draftomen-0.4.0/MANIFEST.in +1 -0
- draftomen-0.4.0/PKG-INFO +448 -0
- draftomen-0.4.0/README.md +420 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/audit.py +199 -32
- draftomen-0.4.0/draftomen/augmented_artifact.py +1081 -0
- draftomen-0.4.0/draftomen/augmented_manifest.py +404 -0
- draftomen-0.4.0/draftomen/augmented_model_client.py +659 -0
- draftomen-0.4.0/draftomen/augmented_public_data.py +338 -0
- draftomen-0.4.0/draftomen/augmented_publication.py +447 -0
- draftomen-0.4.0/draftomen/augmented_training.py +1116 -0
- draftomen-0.4.0/draftomen/augmented_training_data.py +644 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/backtest.py +67 -11
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/benchmark.py +17 -10
- draftomen-0.4.0/draftomen/card_data_client.py +482 -0
- draftomen-0.4.0/draftomen/card_data_export.py +640 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/carddb.py +929 -266
- draftomen-0.4.0/draftomen/cli.py +1938 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/config.py +20 -2
- draftomen-0.4.0/draftomen/corpus.py +1772 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/deckbuilder.py +1218 -32
- draftomen-0.4.0/draftomen/draftmancer.py +1187 -0
- draftomen-0.4.0/draftomen/draftmancer_server.py +305 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/events.py +3 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/mock_session.py +66 -6
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/paths.py +3 -0
- draftomen-0.4.0/draftomen/pickengine.py +3018 -0
- draftomen-0.4.0/draftomen/pool_ledger.py +1084 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/preferences.py +20 -3
- draftomen-0.4.0/draftomen/profile_batch_generation.py +705 -0
- draftomen-0.4.0/draftomen/profile_client.py +1037 -0
- draftomen-0.4.0/draftomen/profile_data_refresh.py +606 -0
- draftomen-0.4.0/draftomen/profile_generation.py +1639 -0
- draftomen-0.4.0/draftomen/profile_generation_execution.py +859 -0
- draftomen-0.4.0/draftomen/profile_generation_stage_policy.py +283 -0
- draftomen-0.4.0/draftomen/profile_input_acquisition.py +1820 -0
- draftomen-0.4.0/draftomen/profile_input_cache.py +1155 -0
- draftomen-0.4.0/draftomen/profile_manifest.py +365 -0
- draftomen-0.4.0/draftomen/profile_publication.py +801 -0
- draftomen-0.4.0/draftomen/profile_refresh_execution.py +1869 -0
- draftomen-0.4.0/draftomen/profile_statistics.py +153 -0
- draftomen-0.4.0/draftomen/progress.py +70 -0
- draftomen-0.4.0/draftomen/public_dump.py +846 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/AppBar.qml +15 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/CardPreview.qml +91 -14
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/LiveDraftView.qml +182 -17
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/Main.qml +9 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/RecentPicksGallery.qml +1 -1
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/RecommendationRow.qml +6 -3
- draftomen-0.4.0/draftomen/qml/SettingsTextField.qml +37 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/SettingsView.qml +216 -95
- draftomen-0.4.0/draftomen/qml/StateBanner.qml +284 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/StatusStrip.qml +48 -0
- draftomen-0.4.0/draftomen/qml/TestDraftDialog.qml +339 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/qmldir +2 -0
- draftomen-0.4.0/draftomen/qt_adapter.py +2069 -0
- draftomen-0.4.0/draftomen/qt_gui.py +1256 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/ranking.py +9 -9
- draftomen-0.4.0/draftomen/refresh_plan.py +865 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/replay.py +125 -47
- draftomen-0.4.0/draftomen/semantic_roles.py +2309 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/session.py +1949 -651
- draftomen-0.4.0/draftomen/set_card_data.py +712 -0
- draftomen-0.4.0/draftomen/set_profile.py +1396 -0
- draftomen-0.4.0/draftomen/sets_manifest.py +253 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/seventeen.py +241 -148
- draftomen-0.4.0/draftomen/test_draft.py +1208 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/tui.py +460 -199
- draftomen-0.4.0/draftomen/watch.py +537 -0
- draftomen-0.4.0/draftomen.egg-info/PKG-INFO +448 -0
- draftomen-0.4.0/draftomen.egg-info/SOURCES.txt +161 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen.egg-info/requires.txt +1 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/pyproject.toml +38 -3
- draftomen-0.4.0/scripts/hob_model_c_training.py +124 -0
- draftomen-0.4.0/tests/test_audit.py +913 -0
- draftomen-0.4.0/tests/test_augmented_artifact.py +362 -0
- draftomen-0.4.0/tests/test_augmented_manifest.py +122 -0
- draftomen-0.4.0/tests/test_augmented_model_client.py +471 -0
- draftomen-0.4.0/tests/test_augmented_public_data.py +618 -0
- draftomen-0.4.0/tests/test_augmented_publication.py +647 -0
- draftomen-0.4.0/tests/test_augmented_training.py +1074 -0
- draftomen-0.4.0/tests/test_augmented_training_data.py +376 -0
- draftomen-0.4.0/tests/test_backtest.py +798 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_benchmark.py +194 -5
- draftomen-0.4.0/tests/test_card_data_client.py +473 -0
- draftomen-0.4.0/tests/test_card_data_export.py +892 -0
- draftomen-0.4.0/tests/test_carddb.py +1144 -0
- draftomen-0.4.0/tests/test_ci_workflow_config.py +55 -0
- draftomen-0.4.0/tests/test_cli.py +3680 -0
- draftomen-0.4.0/tests/test_corpus.py +645 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_deckbuilder.py +857 -3
- draftomen-0.4.0/tests/test_desktop_bundle.py +1231 -0
- draftomen-0.4.0/tests/test_draftmancer.py +1505 -0
- draftomen-0.4.0/tests/test_draftmancer_server.py +469 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_mock_session.py +84 -1
- draftomen-0.4.0/tests/test_pickengine.py +4630 -0
- draftomen-0.4.0/tests/test_pool_ledger.py +582 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_preferences.py +127 -0
- draftomen-0.4.0/tests/test_profile_batch_generation.py +532 -0
- draftomen-0.4.0/tests/test_profile_client.py +1040 -0
- draftomen-0.4.0/tests/test_profile_data_refresh.py +985 -0
- draftomen-0.4.0/tests/test_profile_generation.py +1680 -0
- draftomen-0.4.0/tests/test_profile_generation_execution.py +1034 -0
- draftomen-0.4.0/tests/test_profile_generation_stage_policy.py +193 -0
- draftomen-0.4.0/tests/test_profile_input_acquisition.py +1621 -0
- draftomen-0.4.0/tests/test_profile_input_cache.py +461 -0
- draftomen-0.4.0/tests/test_profile_manifest.py +214 -0
- draftomen-0.4.0/tests/test_profile_publication.py +852 -0
- draftomen-0.4.0/tests/test_profile_refresh_execution.py +1576 -0
- draftomen-0.4.0/tests/test_profile_refresh_publication.py +1514 -0
- draftomen-0.4.0/tests/test_profile_refresh_workflow_config.py +329 -0
- draftomen-0.4.0/tests/test_profile_refresh_workflow_helper.py +1884 -0
- draftomen-0.4.0/tests/test_profile_statistics.py +176 -0
- draftomen-0.4.0/tests/test_progress.py +86 -0
- draftomen-0.4.0/tests/test_public_dump.py +332 -0
- draftomen-0.4.0/tests/test_qt_adapter.py +5746 -0
- draftomen-0.4.0/tests/test_qt_gui.py +10220 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_qt_mock.py +26 -1
- draftomen-0.4.0/tests/test_refresh_plan.py +386 -0
- draftomen-0.4.0/tests/test_replay.py +817 -0
- draftomen-0.4.0/tests/test_semantic_roles.py +826 -0
- draftomen-0.4.0/tests/test_session.py +8549 -0
- draftomen-0.4.0/tests/test_set_card_data.py +309 -0
- draftomen-0.4.0/tests/test_set_profile.py +793 -0
- draftomen-0.4.0/tests/test_sets_manifest.py +174 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_seventeen.py +231 -5
- draftomen-0.4.0/tests/test_test_draft.py +2257 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_tui.py +1336 -486
- draftomen-0.4.0/tests/test_watch.py +1729 -0
- draftomen-0.3.1/PKG-INFO +0 -156
- draftomen-0.3.1/README.md +0 -129
- draftomen-0.3.1/draftomen/cli.py +0 -891
- draftomen-0.3.1/draftomen/pickengine.py +0 -1117
- draftomen-0.3.1/draftomen/qml/StateBanner.qml +0 -189
- draftomen-0.3.1/draftomen/qt_adapter.py +0 -884
- draftomen-0.3.1/draftomen/qt_gui.py +0 -338
- draftomen-0.3.1/draftomen/watch.py +0 -336
- draftomen-0.3.1/draftomen.egg-info/PKG-INFO +0 -156
- draftomen-0.3.1/draftomen.egg-info/SOURCES.txt +0 -87
- draftomen-0.3.1/tests/test_audit.py +0 -379
- draftomen-0.3.1/tests/test_backtest.py +0 -179
- draftomen-0.3.1/tests/test_carddb.py +0 -501
- draftomen-0.3.1/tests/test_cli.py +0 -716
- draftomen-0.3.1/tests/test_desktop_bundle.py +0 -256
- draftomen-0.3.1/tests/test_pickengine.py +0 -1042
- draftomen-0.3.1/tests/test_qt_adapter.py +0 -1124
- draftomen-0.3.1/tests/test_qt_gui.py +0 -4126
- draftomen-0.3.1/tests/test_replay.py +0 -278
- draftomen-0.3.1/tests/test_session.py +0 -3176
- draftomen-0.3.1/tests/test_watch.py +0 -600
- {draftomen-0.3.1 → draftomen-0.4.0}/LICENSE +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/__init__.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/assets/draftomen.icns +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/assets/draftomen.ico +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/assets/draftomen_logo.png +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/cardimages.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/logfollow.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/pool.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/AboutDialog.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/BacktestView.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/BuildView.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/DimensionalButton.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/DimensionalComboBox.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/DimensionalSurface.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/DimensionalTabButton.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/NavigationRail.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/PoolSummaryPanel.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/PrivacyDialog.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/RecentPickThumbnail.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/SettingsSwitch.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qml/Theme.qml +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/qt_mock.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/setinfo.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen/splash.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen.egg-info/dependency_links.txt +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen.egg-info/entry_points.txt +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/draftomen.egg-info/top_level.txt +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/setup.cfg +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_cardimages.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_events.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_extract_changelog.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_logfollow.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_paths.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_pool.py +0 -0
- {draftomen-0.3.1 → draftomen-0.4.0}/tests/test_render_homebrew_formula.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include scripts/hob_model_c_training.py
|
draftomen-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: draftomen
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: An unofficial Quick Draft assistant for MTG Arena
|
|
5
|
+
Author: Andrea Grandi
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/andreagrandi/draftomen
|
|
8
|
+
Project-URL: Repository, https://github.com/andreagrandi/draftomen
|
|
9
|
+
Project-URL: Issues, https://github.com/andreagrandi/draftomen/issues
|
|
10
|
+
Keywords: draft,magic-the-gathering,mtg-arena,terminal,tui
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Games/Entertainment
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: pyside6<7,>=6.9
|
|
24
|
+
Requires-Dist: python-socketio[client]<6,>=5.16.4
|
|
25
|
+
Requires-Dist: textual>=8.2.8
|
|
26
|
+
Requires-Dist: textual-image>=0.13.2
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="https://raw.githubusercontent.com/andreagrandi/draftomen/master/docs/assets/draftomen_banner.png" alt="Draft Omen banner" width="100%">
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
# Draft Omen
|
|
34
|
+
|
|
35
|
+
Draft Omen is an unofficial desktop draft assistant for MTG Arena Quick Drafts. Its PySide6/QML application reads Arena's local `Player.log`, recognizes each pack and pick, and ranks the available cards while you draft. When the draft is complete, it also suggests a 40-card deck from your pool. A terminal interface with the same draft behavior is available as `draftomen-tui`.
|
|
36
|
+
|
|
37
|
+
Draft Omen is read-only: it does not write to, inject into, or automate MTG Arena. Card details come from [Scryfall](https://scryfall.com/) and draft statistics come from [17Lands](https://www.17lands.com/).
|
|
38
|
+
|
|
39
|
+
## Screenshots
|
|
40
|
+
|
|
41
|
+
### Live Draft GUI — pick recommendations
|
|
42
|
+
|
|
43
|
+
The Live Draft view shows Pack 1, Pick 3 with 12 cards available and Glóin the Mighty selected. Its DO Score, 17Lands win rate, grade, and color fit appear alongside focused-card details and a pool summary.
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
### Suggested deck GUI
|
|
48
|
+
|
|
49
|
+
After the draft, the Suggested deck view shows an automatic UR pair and a 40-card build with 23 spells, 17 lands, a mana base and curve, grouped main-deck spells, and selected-card details.
|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
## How recommendations work
|
|
54
|
+
|
|
55
|
+
Draft Omen keeps the data behind every recommendation visible instead of presenting a black-box pick order:
|
|
56
|
+
|
|
57
|
+
- **17Lands ratings:** each card shows its Games-in-Hand win rate (`17L WR`) and a 17Lands-style grade. Quick Draft data is preferred; Premier Draft data is used as a fallback when Quick Draft samples are missing or too small.
|
|
58
|
+
- **DO Score:** the default 0-100 ranking normalizes 17Lands win rates across the set. A card without a reliable sample starts from a neutral score of 50, adjusted by its Average Last Seen At (`ALSA`) when available. The five freely available basic lands instead score 0 and rank after draftable cards.
|
|
59
|
+
- **Color fit:** early picks stay open. From pick 6 onward, scores gradually favor the colors supported by the drafted pool; from pick 16, on-color cards receive the full bonus and off-color cards the full penalty. Strong picks influence the inferred color pair more than filler.
|
|
60
|
+
- **Close early picks:** when two cards have similar scores, set- and format-specific 17Lands color-pair win rates can break the tie without forcing an early commitment.
|
|
61
|
+
- **Conservative splashing:** an `A`-range, single-pip card can be marked as a visible third-color splash when it is materially better than the on-color choices and the pool can support its mana. Draft Omen limits this to one extra color and two cards.
|
|
62
|
+
- **Transparent alternatives:** press `s` to compare rankings by DO Score, raw 17Lands win rate, ALSA, or mana value. The interface also identifies neutral-prior and Premier-fallback rows.
|
|
63
|
+
- **Deck suggestion:** the builder evaluates two-color pairs using card quality and 17Lands pair performance, then chooses spells and lands while considering creatures, curve, colored mana requirements, and cached 17Lands deck-structure targets when available.
|
|
64
|
+
|
|
65
|
+
DO Score is the default because it performed better than raw 17Lands win rate in Draft Omen's offline pick benchmarks. It is still guidance rather than a perfect pick order: public statistics reflect the decks, players, and contexts in which cards were played.
|
|
66
|
+
|
|
67
|
+
For the complete methodology, see [pick scoring](docs/pick-scoring.md), [benchmarking](docs/benchmarking.md), and the [deck builder](docs/deck-builder.md).
|
|
68
|
+
|
|
69
|
+
## How to use it
|
|
70
|
+
|
|
71
|
+
### 1. Install
|
|
72
|
+
|
|
73
|
+
On macOS, install Draft Omen with Homebrew:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
brew install andreagrandi/tap/draftomen
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
On other platforms, [install uv](https://docs.astral.sh/uv/getting-started/installation/) and run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv tool install draftomen
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Enable Arena logs
|
|
86
|
+
|
|
87
|
+
In MTG Arena, open **Settings → Account**, enable **Detailed Logs (Plugin Support)**, and restart Arena.
|
|
88
|
+
|
|
89
|
+
### 3. Start Draft Omen
|
|
90
|
+
|
|
91
|
+
Start Draft Omen before entering a Quick Draft:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
draftomen
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The PySide6/QML desktop application loads card metadata when needed, watches
|
|
98
|
+
Arena's standard log location, detects the set, and follows the draft
|
|
99
|
+
automatically. Native and terminal live sessions use the shared set-profile
|
|
100
|
+
lifecycle as their sole ratings authority. They load a validated local profile
|
|
101
|
+
cache first, so a warm valid profile is active immediately while an allowed
|
|
102
|
+
hosted-profile refresh proceeds. If the production manifest (or an explicit
|
|
103
|
+
override) is absent, inaccessible, invalid, or has no profile for the set, the
|
|
104
|
+
cached profile is retained; with no usable cache, deterministic fallback scoring
|
|
105
|
+
remains active. Live sessions do not load ratings directly from 17Lands.
|
|
106
|
+
|
|
107
|
+
Native and terminal live commands use
|
|
108
|
+
`https://www.draftomen.com/profiles/manifest.json` by default. For the desktop
|
|
109
|
+
command, use `--profile-manifest-url URL` to select an explicit HTTPS manifest,
|
|
110
|
+
or `--offline-profiles` to select profile-only offline mode:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
draftomen --profile-manifest-url "$PROFILE_MANIFEST_URL"
|
|
114
|
+
draftomen --offline-profiles
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`--offline-profiles` selects `ProfileNetworkPolicy.OFFLINE` and takes
|
|
118
|
+
precedence over profile networking only. It does not disable Scryfall card
|
|
119
|
+
metadata, card images, or static card-data networking.
|
|
120
|
+
|
|
121
|
+
The TUI `d` action and the native ratings refresh control use the existing
|
|
122
|
+
shared profile-refresh command boundary. A newer validated profile reports an
|
|
123
|
+
`updated` outcome and changes recommendations in place; an equal result reports
|
|
124
|
+
`unchanged` and leaves the current ratings active. Failed, offline, or missing
|
|
125
|
+
refreshes retain the last usable cache when ratings exist; with no usable
|
|
126
|
+
profile, deterministic fallback scoring remains active. Repeated requests
|
|
127
|
+
coalesce, and `watch --plain` has no command UI.
|
|
128
|
+
|
|
129
|
+
### Terminal interface
|
|
130
|
+
|
|
131
|
+
For a terminal workflow, use the stable `draftomen-tui` command. It provides
|
|
132
|
+
watch, replay, build, backtest, benchmark, data-refresh, `export-set-data`,
|
|
133
|
+
local `generate-profile`, and `refresh-profile` commands:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
draftomen-tui
|
|
137
|
+
draftomen-tui watch
|
|
138
|
+
draftomen-tui watch --plain
|
|
139
|
+
draftomen-tui watch --offline-profiles
|
|
140
|
+
draftomen-tui watch --profile-manifest-url "$PROFILE_MANIFEST_URL"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Terminal `watch` and `watch --plain` use the production hosted manifest by
|
|
144
|
+
default. `--profile-manifest-url` selects an alternate HTTPS manifest, and
|
|
145
|
+
`--offline-profiles` disables only profile networking; Scryfall card data,
|
|
146
|
+
images, and other static data sources retain their own network/cache behavior.
|
|
147
|
+
|
|
148
|
+
To generate a deterministic set profile from pinned input files, use
|
|
149
|
+
`generate-profile` with explicit set, format, stage, timezone-aware timestamp,
|
|
150
|
+
card-database, and output paths. The producer and cache workflow, including
|
|
151
|
+
remote manifest fields, validation, refresh, recovery, and explicit provider
|
|
152
|
+
ingestion, is documented in [set profiles](docs/set-profiles.md).
|
|
153
|
+
|
|
154
|
+
### Static set card data
|
|
155
|
+
|
|
156
|
+
The live card lookup uses one schema-versioned (schema version `1`), canonical
|
|
157
|
+
Scryfall artifact per Arena set. Artifacts are published at
|
|
158
|
+
`website/public/card-data/<lowercase-set-code>.json.gz` and hosted at
|
|
159
|
+
`https://www.draftomen.com/card-data/<lowercase-set-code>.json.gz`.
|
|
160
|
+
Generate one set by exact code or full name, or discover every eligible set:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
draftomen-tui export-set-data SET
|
|
164
|
+
draftomen-tui export-set-data
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Discovery makes one `17Lands /data/expansions` request and one Scryfall
|
|
168
|
+
default-cards bulk acquisition. No-argument discovery requires at least 200
|
|
169
|
+
distinct Arena card identities per set; paper-only, Cube, Chaos, and Remix
|
|
170
|
+
sets are excluded. `--inventory-file PATH` and `--bulk-file PATH` replace
|
|
171
|
+
those network sources for reproducible or offline runs. The all-set command
|
|
172
|
+
validates existing artifacts, publishes pending sets in code order, and can be
|
|
173
|
+
rerun to resume from the first pending set.
|
|
174
|
+
|
|
175
|
+
### Sets manifest
|
|
176
|
+
|
|
177
|
+
`website/public/sets/manifest.json`, hosted at
|
|
178
|
+
`https://www.draftomen.com/sets/manifest.json`, lists every set with a
|
|
179
|
+
card-data file. Each entry records the set name, the card-data URL, byte size
|
|
180
|
+
and SHA-256, the published profile formats with their maturity, and the
|
|
181
|
+
augmented model metrics when one exists. `export-set-data`,
|
|
182
|
+
`build-augmented-set` and the Profile Refresh publication regenerate it from
|
|
183
|
+
the files under `website/public`, and a test fails when the committed file
|
|
184
|
+
no longer matches them.
|
|
185
|
+
|
|
186
|
+
In live mode, Draft Omen detects the set before loading its selected artifact.
|
|
187
|
+
The default cache path is the application-data `card-data/<set-code>.json.gz`
|
|
188
|
+
file (normally `~/.draftomen/card-data/<set-code>.json.gz`); a valid cache is
|
|
189
|
+
reused without network access. Card metadata is automatically loaded at most
|
|
190
|
+
once per pre-draft detection lifecycle for a selected set; no card-data network
|
|
191
|
+
request is made after `DraftStartedEvent`.
|
|
192
|
+
Printed card fields and images come from Scryfall; 17Lands ratings and
|
|
193
|
+
statistics remain a separate data source and are not embedded in card-data
|
|
194
|
+
artifacts.
|
|
195
|
+
|
|
196
|
+
In the TUI, press `r` to retry a recoverable card-data error. Network repair is
|
|
197
|
+
available only before draft start; after `DraftStartedEvent`, retries use the
|
|
198
|
+
local cache only.
|
|
199
|
+
|
|
200
|
+
### Hosted set profiles and profile-only offline mode
|
|
201
|
+
|
|
202
|
+
Native and terminal set-profile loading is local-first and hosted by default. A
|
|
203
|
+
validated flat cache is used before any network refresh, so a warm valid cache
|
|
204
|
+
remains active while the production manifest is checked. The default manifest
|
|
205
|
+
for both live commands is:
|
|
206
|
+
|
|
207
|
+
```text
|
|
208
|
+
https://www.draftomen.com/profiles/manifest.json
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Override it for a different HTTPS manifest:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
draftomen --profile-manifest-url "$PROFILE_MANIFEST_URL"
|
|
215
|
+
draftomen-tui watch --profile-manifest-url "$PROFILE_MANIFEST_URL"
|
|
216
|
+
draftomen-tui watch --plain --profile-manifest-url "$PROFILE_MANIFEST_URL"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Use `--offline-profiles` for profile-only offline operation:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
draftomen --offline-profiles
|
|
223
|
+
draftomen-tui watch --offline-profiles
|
|
224
|
+
draftomen-tui watch --plain --offline-profiles
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
This flag selects `ProfileNetworkPolicy.OFFLINE` for set profiles only and
|
|
228
|
+
takes precedence over profile networking. It does not disable Scryfall card
|
|
229
|
+
metadata, card images, or static card-data networking; those sources retain
|
|
230
|
+
their own cache and network policies.
|
|
231
|
+
|
|
232
|
+
When a hosted manifest or artifact is missing, unreachable, invalid, or weaker
|
|
233
|
+
than the cached profile, the last-good cache remains authoritative. If there
|
|
234
|
+
is no usable cache, deterministic fallback scoring remains active; live
|
|
235
|
+
sessions do not load ratings directly from 17Lands. The TUI `d` action and the
|
|
236
|
+
native ratings refresh control request the same forced hosted-profile refresh.
|
|
237
|
+
A newer validated profile reports an `updated` outcome and changes
|
|
238
|
+
recommendations in place; an equal result reports `unchanged` and leaves
|
|
239
|
+
ratings active. Failed, offline, or missing refreshes retain the last usable
|
|
240
|
+
cache when ratings exist; with no usable profile, deterministic fallback
|
|
241
|
+
scoring remains active. Repeated requests coalesce, and `watch --plain` has
|
|
242
|
+
no command UI.
|
|
243
|
+
|
|
244
|
+
Manual `refresh-profile` remains an explicit producer/client operation:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
draftomen-tui refresh-profile --set-code SET --format FORMAT \
|
|
248
|
+
--manifest-url "$PROFILE_MANIFEST_URL"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Draft Omen does not bundle a hosted manifest. Producer generation, website
|
|
252
|
+
publication, and Python/native release workflows remain independent of runtime
|
|
253
|
+
profile consumption. Native applications may still carry a validated baseline
|
|
254
|
+
profile resource for local fallback; hosted refresh never mutates that
|
|
255
|
+
resource.
|
|
256
|
+
|
|
257
|
+
For development-only semantic analysis, use the reproducible [card corpus
|
|
258
|
+
workflow](docs/corpus.md). It keeps pinned source bytes and locks outside
|
|
259
|
+
tracked data and emits deterministic artifacts for offline consumers.
|
|
260
|
+
|
|
261
|
+
Use the arrow keys or `j`/`k` to browse cards, `s` to change the ranking,
|
|
262
|
+
`b` to open the current build, `c` to configure the view and optional splash
|
|
263
|
+
recommendations, `d` to refresh the hosted profile in the TUI, and `q` to quit.
|
|
264
|
+
|
|
265
|
+
### Visual development
|
|
266
|
+
|
|
267
|
+
For deterministic visual development, launch the explicit forced-mock entry
|
|
268
|
+
point:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
draftomen-gui-mockup
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
For an automated, non-interactive GUI smoke check, use the default command
|
|
275
|
+
with its mock provider and bounded smoke flag:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
QT_QPA_PLATFORM=offscreen draftomen --provider mock --smoke-test
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
See the [desktop GUI guide](docs/gui-mockup.md) for live and mock launch
|
|
282
|
+
options, selectable states, and responsive review targets. For reproducible
|
|
283
|
+
unsigned development bundles, see the [desktop bundle guide](docs/desktop-bundles.md).
|
|
284
|
+
|
|
285
|
+
### Draftmancer protocol development
|
|
286
|
+
|
|
287
|
+
The Draftmancer protocol smoke requires Node.js 22 and a sibling checkout;
|
|
288
|
+
do not put the simulator in a tracked or vendored directory. From the parent
|
|
289
|
+
directory of this repository:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
git clone https://github.com/Senryoku/Draftmancer.git
|
|
293
|
+
cd Draftmancer
|
|
294
|
+
git checkout --detach df08e5ef647aae54e0b1c569e70b4b2aa5e0016c
|
|
295
|
+
npm ci
|
|
296
|
+
npm run build-server
|
|
297
|
+
DISABLE_PERSISTENCE=TRUE npm start
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Download Scryfall's complete default-cards bulk source once through the
|
|
301
|
+
development corpus cache; the smoke never performs per-card API requests:
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
uv run draftomen-tui corpus-build --selection explicit --set-code HOB
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
With the pinned server running, open a second terminal in Draft Omen and run:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
uv run python scripts/draftmancer_smoke.py \
|
|
311
|
+
--draftmancer-dir ../Draftmancer
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
The helper, rather than ordinary Draft Omen startup, owns the simulator
|
|
315
|
+
connection. It chooses the first simulator card instance deterministically
|
|
316
|
+
only to complete the protocol smoke; it does not apply recommendations or
|
|
317
|
+
manage the Draftmancer service.
|
|
318
|
+
|
|
319
|
+
HOB is the default and required real-smoke target. The helper maps each
|
|
320
|
+
Draftmancer Scryfall printing ID through the local bulk file's `oracle_id` to
|
|
321
|
+
the canonical HOB Arena grpId. Missing, ambiguous, or unknown identities fail
|
|
322
|
+
before an offer reaches `LiveSession`. Pass `--scryfall-bulk-file` only when
|
|
323
|
+
the complete local JSONL bulk cache is stored somewhere other than
|
|
324
|
+
`.draftomen/corpus-cache/sources/scryfall-default-cards.jsonl.gz`.
|
|
325
|
+
|
|
326
|
+
The same pinned checkout and bulk source drive the headless test draft, which
|
|
327
|
+
drafts a complete three-pack event through production recommendations and the
|
|
328
|
+
normal deck builder:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
uv run draftomen-tui test-draft \
|
|
332
|
+
--draftmancer-dir ../Draftmancer
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
`test-draft` always drafts automatically: it confirms the first ranked
|
|
336
|
+
recommendation of every offered pack, prints one
|
|
337
|
+
`Pack N pick M: <card> (grpId <id>)` line per accepted pick, and finishes with
|
|
338
|
+
the ordinary deck-builder report. It reads the configured card-data cache and
|
|
339
|
+
set profiles from the normal application directory, keeps simulated draft state
|
|
340
|
+
and audit records in a private temporary directory, and neither reads nor
|
|
341
|
+
changes Arena draft history.
|
|
342
|
+
|
|
343
|
+
`--set-code` accepts any set present in both Draftmancer's `MTGASets` and the
|
|
344
|
+
local card-data cache (HOB by default); an unsupported set fails before any
|
|
345
|
+
pick, and a booster printing that cannot be resolved to one canonical Arena
|
|
346
|
+
grpId fails before that pack is submitted.
|
|
347
|
+
|
|
348
|
+
`--server-url`, `--scryfall-bulk-file`, and `--timeout` mirror the smoke
|
|
349
|
+
defaults, and `--profile-manifest-url` / `--offline-profiles` behave as in
|
|
350
|
+
`watch`. Startup, drafting, and deck-building failures report
|
|
351
|
+
`test-draft failed: <reason>` and exit nonzero; the command never starts,
|
|
352
|
+
stops, or configures the Draftmancer service.
|
|
353
|
+
|
|
354
|
+
The native application serves the same developer checkout itself. With the Mocked
|
|
355
|
+
Draft setting enabled the application starts the pinned checkout on a port it
|
|
356
|
+
picks, adopts a server that already answers the configured location, and stops
|
|
357
|
+
only the process it started when the draft is left or the application exits. The
|
|
358
|
+
three source values live in Settings → DEVELOPER next to the Mocked Draft switch —
|
|
359
|
+
the Draftmancer checkout directory, the Draftmancer server URL, and the Scryfall
|
|
360
|
+
bulk file — each prefilled with the application-data location, editable in the
|
|
361
|
+
running app, and still overridden by `--draftmancer-dir`, `--test-draft-server-url`,
|
|
362
|
+
and `--scryfall-bulk-file`.
|
|
363
|
+
|
|
364
|
+
Mocked Draft reads that Scryfall bulk file for printed card identities, and it does
|
|
365
|
+
not ship with the file. When the file is missing, the dialog offers **Download
|
|
366
|
+
Scryfall data**: the application fetches Scryfall's `default_cards` bulk JSONL (about
|
|
367
|
+
80 MB, gzip) from `https://api.scryfall.com/bulk-data` and installs it as
|
|
368
|
+
`corpus-cache/sources/scryfall-default-cards.jsonl.gz` under the application data
|
|
369
|
+
directory — the path the Scryfall bulk file setting shows. The download runs in the
|
|
370
|
+
background with progress, never installs a partial file over an existing one, and
|
|
371
|
+
leaves the dialog ready without a restart. Nothing is downloaded automatically.
|
|
372
|
+
|
|
373
|
+
The native app journeys need the enabled setting instead of a manually managed server:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
uv run draftomen
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
The dialog offers the sets the pinned checkout and the local card-data cache
|
|
380
|
+
both provide (HOB, the application's default test-draft set, whenever both have
|
|
381
|
+
it) and lets the developer choose Manual or Auto. Manual mode confirms the
|
|
382
|
+
selected recommendation with the **Pick** button in the ordinary live drafting
|
|
383
|
+
view and leaves the run through the dialog's **Leave test draft** button, while
|
|
384
|
+
Auto reuses the normal completed-draft and build surfaces. Without the enabled
|
|
385
|
+
setting no Mocked Draft control is present, and the Pick button stays hidden
|
|
386
|
+
during ordinary Arena drafting. The TUI/CLI commands and the compiled-bundle
|
|
387
|
+
helper keep requiring the developer-managed server above.
|
|
388
|
+
|
|
389
|
+
The complete acceptance workflow is three developer-run commands. The headless and
|
|
390
|
+
compiled-bundle commands run against the developer-managed pinned server above,
|
|
391
|
+
while the interactive launch uses the enabled Mocked Draft setting and its
|
|
392
|
+
self-served checkout:
|
|
393
|
+
|
|
394
|
+
A headless auto draft proves the production recommendation and deck-building
|
|
395
|
+
path end to end against the real protocol:
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
uv run draftomen-tui test-draft \
|
|
399
|
+
--draftmancer-dir ../Draftmancer
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
The compiled bundle proves both native journeys in one invocation. Auto drafts
|
|
403
|
+
to the ordinary build result, and Manual confirms five picks through the real
|
|
404
|
+
Test Draft controls. The helper requires each journey's summary line and proves
|
|
405
|
+
the external server is still alive before and after:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
uv run python tests/bundle_smoke.py --test-draft \
|
|
409
|
+
--draftmancer-dir ../Draftmancer \
|
|
410
|
+
--scryfall-bulk-file .draftomen/corpus-cache/sources/scryfall-default-cards.jsonl.gz \
|
|
411
|
+
--app-dir <prepared-dir> \
|
|
412
|
+
dist-native/macos-unsigned/Draftomen-unsigned-macos.app
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
An interactive launch proves a developer can start a simulated draft, confirm
|
|
416
|
+
picks, and leave it by hand through those same controls:
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
uv run draftomen
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
To run the same pinned server through a compiled bundle instead of the source
|
|
423
|
+
tree, see [Native Test Draft smoke
|
|
424
|
+
(manual)](docs/desktop-bundles.md#native-test-draft-smoke-manual) in the desktop
|
|
425
|
+
bundle guide, which lists the prerequisites, the prepared app directory, and
|
|
426
|
+
both journey summary lines.
|
|
427
|
+
|
|
428
|
+
Live recommendations currently support Quick Draft. Windows support is best-effort.
|
|
429
|
+
|
|
430
|
+
## Local draft audit data
|
|
431
|
+
|
|
432
|
+
Live sessions started with `draftomen-tui`, including `watch --plain`, keep an
|
|
433
|
+
independent, append-only JSONL audit log for every draft under
|
|
434
|
+
`~/.draftomen/audit/drafts/<account-id>/<draft-id>.jsonl`. Each record includes
|
|
435
|
+
the offered pack, pool snapshot, ratings source, scoring configuration, complete
|
|
436
|
+
candidate calculations, splash eligibility and mana-source reasoning, all
|
|
437
|
+
supported rankings, the recommendation visible when the pick was made, and the
|
|
438
|
+
card actually chosen. Stable record IDs prevent
|
|
439
|
+
startup scans and log rotation from rewriting prior evidence.
|
|
440
|
+
|
|
441
|
+
Offline `replay` and backtest commands do not write audit records. For the schema
|
|
442
|
+
and retention details, see [draft audit logging](docs/draft-audit-log.md).
|
|
443
|
+
|
|
444
|
+
## Branding and compliance
|
|
445
|
+
|
|
446
|
+
Draft Omen is not affiliated with, sponsored by, approved by, or endorsed by Wizards of the Coast, Scryfall, or 17Lands.
|
|
447
|
+
|
|
448
|
+
Draft Omen is unofficial Fan Content permitted under the Fan Content Policy. Not approved/endorsed by Wizards. Portions of the materials used are property of Wizards of the Coast. ©Wizards of the Coast LLC. Card data from Scryfall and 17Lands; neither service endorses this tool.
|