kfm-cli 0.1.1__py3-none-win_amd64.whl

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.
Binary file
@@ -0,0 +1,158 @@
1
+ Metadata-Version: 2.4
2
+ Name: kfm-cli
3
+ Version: 0.1.1
4
+ Classifier: Environment :: Console
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: Operating System :: POSIX :: Linux
7
+ Classifier: Operating System :: MacOS
8
+ Classifier: Operating System :: Microsoft :: Windows
9
+ Classifier: Programming Language :: Rust
10
+ Classifier: Topic :: Games/Entertainment
11
+ Summary: kfm: the Kung Fu Monkeys bot ladder from the command line (log in, build, test, submit, replays)
12
+ Keywords: kung-fu-monkeys,bots,webassembly,ladder,cli
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
15
+ Project-URL: Documentation, https://github.com/minip8/kung-fu-monkeys-bots/blob/main/cli/README.md
16
+ Project-URL: Homepage, https://github.com/minip8/kung-fu-monkeys-bots
17
+ Project-URL: Source, https://github.com/minip8/kung-fu-monkeys-bots/tree/main/cli
18
+
19
+ # kfm: the Kung Fu Monkeys bot ladder from the command line
20
+
21
+ `kfm` logs you in to the [Kung Fu Monkeys](https://github.com/minip8/kung-fu-monkeys) bot
22
+ ladder, builds a bot with the ladder's own recipe, plays it against the reference bot with the
23
+ engine's released `kfm_arena`, submits it, and follows its matches and replays. It is one
24
+ static binary; it talks to the ladder over its documented HTTP API
25
+ ([`docs/ladder-api.md`](https://github.com/minip8/kung-fu-monkeys-bots/blob/main/docs/ladder-api.md))
26
+ and nothing else.
27
+
28
+ ## Install
29
+
30
+ ```sh
31
+ uv tool install kfm-cli # or: pipx install kfm-cli
32
+ uvx --from kfm-cli kfm --help # or run it once without installing
33
+ ```
34
+
35
+ The PyPI project is **`kfm-cli`** (the name `kfm` is taken on PyPI by an unrelated package);
36
+ the command it installs is `kfm`. The wheels hold the binary only, for Linux x86_64 (static,
37
+ musl), macOS arm64 and Windows x86_64; the same wheels are on the bots repository's
38
+ [releases page](https://github.com/minip8/kung-fu-monkeys-bots/releases). From a checkout of
39
+ the repository: `cargo install --path cli`.
40
+
41
+ `kfm build` needs [Docker](https://docs.docker.com/get-docker/) (or Podman, `DOCKER=podman`)
42
+ for the ladder's build image, or a clang that targets wasm32 for `--local`. `kfm test`
43
+ downloads its runner itself.
44
+
45
+ ## The five-minute path
46
+
47
+ You need an account and a team: sign in on the portal, <https://bots.kfm.minip8.com/>, with
48
+ GitHub or Google and create a team there (a solo player is a team of one).
49
+
50
+ ```sh
51
+ git clone --depth 1 https://github.com/minip8/kung-fu-monkeys-bots.git
52
+ cp -r kung-fu-monkeys-bots/examples/starter mybot && cd mybot # a bot is a directory of sources
53
+ kfm login # the browser confirms; a `submit` token is stored
54
+ kfm build # out/bot.wasm, built in the ladder's image and checked
55
+ kfm test # 10 matches of the ranked 5v5 against ref:hard: wins, faults, fuel
56
+ kfm submit --wait --activate # the ladder builds and validates it; then it is your ranked bot
57
+ kfm matches list --team "My Team" # once the scheduler has paired it (every few minutes)
58
+ kfm replay open <match id> # the game in its own release's browser client
59
+ ```
60
+
61
+ Edit `bot.cpp`, `kfm build && kfm test`, repeat; `kfm test --seed 7` plays other seeds. The
62
+ SDK (`kfm_bot.hpp` over `kfm_bot.h`) is on the include path of every build, so a bot directory
63
+ holds only its own sources.
64
+
65
+ ## Commands
66
+
67
+ | Command | What |
68
+ |---|---|
69
+ | `kfm login [--no-browser]` | Opens the ladder's login page, which asks you to authorize "kfm on <this computer>"; stores the `submit` token it creates. `--no-browser` prints the URL and waits (from another machine, forward the printed port with `ssh -L` first). |
70
+ | `kfm logout` | Revokes the stored token on the ladder and forgets it. |
71
+ | `kfm whoami` | The account the token belongs to and its teams. |
72
+ | `kfm build [DIR] [-o OUT.wasm] [--local] [--image IMAGE]` | Builds every `.c`, `.cc` and `.cpp` file directly in DIR (default `.`) into `DIR/out/bot.wasm` with the ladder's recipe, then checks the module as the host will (size, exports, imports, memory). Default: in the pinned build image under Docker, with the ladder's sandbox flags (no network, read-only source, 2 GiB, 120 s); the log goes to `build.log` beside the module. `--local`: with a local clang (`CLANG`, `clang` on `PATH`, `$EMSDK`, `~/emsdk`), byte-identical to the ladder's build with emsdk 6.0.13. |
73
+ | `kfm test [MODULE] [--against SPEC] [--matches N] [--mode MODE] [--ffa] [--engine-tag TAG] [--arena PATH] [--seed S] [--ticks N]` | Plays MODULE (default `out/bot.wasm`) in the ranked shape: its five slots against five `ref:hard` in the `contest` mode, `--rotate` so every pair plays both sides, 10 matches. Prints each match, wins, draws and losses, faults (traps, ticks over budget, bad returns, dead slots) and `fuel_max`; exits 1 if the module faulted (the ladder's validation rejects that). `--against` takes `ref:easy`, `ref:medium` or another module; `--ffa` plays a free-for-all against three. The runner is the engine's released `kfm_arena`, downloaded once per release and checked against the release's `SHA256SUMS`; `--arena PATH` uses a local one. |
74
+ | `kfm submit [DIR] [--team NAME\|ID] [--entry SUBDIR] [--language cpp] [--activate] [--wait]` | Zips DIR (regular files only; `.git/`, `out/`, `.kfm/`, `*.wasm` and links left out; refused locally past the ladder's 4 MiB zipped, 256 files or 16 MiB), uploads it with its manifest and prints the submission's id and state. `--wait` follows it to `ready`, `failed` or `rejected` (printing the build log on failure, exit 3); `--activate` waits and then makes it the team's ranked bot. The team defaults to your only one. |
75
+ | `kfm bots list [--team T]` | The team's submissions: state, active, module hash, ranked games and faults, error. |
76
+ | `kfm bots activate <submission> [--team T]` | Makes a ready submission its team's ranked bot. |
77
+ | `kfm bots log <submission>` | Its build and validation log. |
78
+ | `kfm matches list [--team T] [--season S] [--page N]` | Ranked games, newest first (every team's without `--team`; T is a team id or one of your teams' names). |
79
+ | `kfm matches show <match>` | One game: both sides, scores, kills, rating changes, faults, the seed and hashes to re-run it, the viewer URL. |
80
+ | `kfm ladder [--season S] [--page N]` | The board: rank, rating and deviation, record. |
81
+ | `kfm seasons` | The seasons, the current one marked, and the engine release new games run on. |
82
+ | `kfm replay get <match> [-o FILE]` | Downloads the game's `.kfmr` (default `<match>.kfmr`). |
83
+ | `kfm replay open <match> [--no-browser]` | Prints the replay's viewer URL (the browser client of the game's own release) and opens it. |
84
+
85
+ Every command takes `--server URL` and `--json`, which prints the ladder's raw JSON (for
86
+ `kfm test`, `kfm_arena`'s JSON lines, with the summary on stderr) instead of the summary.
87
+
88
+ ## Configuration
89
+
90
+ `kfm login` writes `config.toml`, readable by you only (mode 0600), in the platform's config
91
+ directory: `~/.config/kfm/config.toml` on Linux (`$XDG_CONFIG_HOME/kfm/`), `~/Library/Application
92
+ Support/kfm/config.toml` on macOS, `%APPDATA%\kfm\config\config.toml` on Windows.
93
+
94
+ ```toml
95
+ server = "https://bots.kfm.minip8.com" # the ladder; the default when absent
96
+ token = "kfm_…" # the API token kfm login stored (scope submit)
97
+ token_id = "0190f0f0-…" # so kfm logout can revoke it
98
+ token_name = "kfm on laptop" # its name on the portal
99
+ ```
100
+
101
+ The stored token is sent only to the server it was made for: `--server` naming another ladder
102
+ runs logged out there (log in to it with `kfm --server URL login`, which replaces the file's
103
+ pair). Revoke the token on the portal or with `kfm logout`.
104
+
105
+ | Variable | Meaning |
106
+ |---|---|
107
+ | `KFM_SERVER` | The ladder, as `--server`. |
108
+ | `KFM_TOKEN` | A token to use instead of the stored one (CI: a `submit` token made on the portal). |
109
+ | `KFM_CONFIG` | Another configuration file. |
110
+ | `KFM_CACHE_DIR` | Another cache directory (default the platform's: `~/.cache/kfm` on Linux) for the downloaded runners and the SDK of `--local`. |
111
+ | `KFM_BUILD_IMAGE` | The build image, as `--image`. |
112
+ | `DOCKER` | The container engine (`docker`; `podman` takes the same flags). |
113
+ | `CLANG`, `EMSDK` | The compiler of `kfm build --local`. |
114
+ | `KFM_SDK_DIR` | An `sdk/` directory to compile against instead of the one built into kfm. |
115
+ | `KFM_ARENA` | A local `kfm_arena`, as `--arena`. |
116
+ | `KFM_RELEASE_URL`, `KFM_ENGINE_REPO` | Where runners are downloaded from (a mirror; another GitHub repository than `minip8/kung-fu-monkeys`). |
117
+
118
+ ## Pins
119
+
120
+ Two releases are fixed when the binary is built (`cli/build.rs`), so a given `kfm` builds and
121
+ plays the way its release does:
122
+
123
+ - **The build image**: `ghcr.io/minip8/kfm-bot-build:<tag>`, `<tag>` this kfm's release: the
124
+ `KFM_BOTS_TAG` environment variable at build time (the release workflow sets it to the tag
125
+ it builds, after checking it is `v` + the crate version), else `v` + the version in
126
+ `Cargo.toml`. `kfm --version` names the version; `--image` or `KFM_BUILD_IMAGE` runs another
127
+ image.
128
+ - **The engine release** of `kfm test` when the ladder names none: `KFM_ENGINE_TAG` at build
129
+ time, else `tag=` of the repository's `engine.lock`. Logged in, `kfm test` asks the ladder
130
+ which release new games run on (`GET /seasons`' `engine_tag`) and plays that one, so you see
131
+ a release's changes before the scheduler does; `--engine-tag` names one yourself.
132
+
133
+ The SDK headers `kfm build --local` compiles against are the repository's `sdk/` at build time,
134
+ embedded in the binary.
135
+
136
+ ## Exit codes
137
+
138
+ | Code | Meaning |
139
+ |---|---|
140
+ | 0 | Done. |
141
+ | 1 | An error: the ladder's, shown as `kfm: <message> (<code>)` (the codes of `docs/ladder-api.md` §2), or a failed build, download or match, or a module that faulted in `kfm test`. |
142
+ | 2 | Usage: a bad flag, a missing module or directory, several teams and no `--team` (`ambiguous`). |
143
+ | 3 | `kfm submit --wait` (or `--activate`): the submission failed to build or was rejected by validation. |
144
+
145
+ ## Development
146
+
147
+ ```sh
148
+ cd cli
149
+ cargo fmt --check && cargo clippy --all-targets --locked -- -D warnings && cargo test --locked
150
+ uvx maturin build --release # the wheel, in target/wheels/
151
+ ```
152
+
153
+ The tests run the real binary against a fake ladder in process (`tests/ladder.rs`); the
154
+ toolchain tests (`tests/toolchain.rs`) build `examples/` in the image (`KFM_TEST_BUILD_IMAGE`,
155
+ default `kfm-bot-build:local`) and with a local emsdk clang, and play them with a `kfm_arena`
156
+ (`KFM_TEST_ARENA`, default `../.kfm/kfm_arena`), each skipping with a message when its tool is
157
+ missing.
158
+
@@ -0,0 +1,5 @@
1
+ kfm_cli-0.1.1.data/scripts/kfm.exe,sha256=Vspf0-UJBDACRR886osbaXuShw-DD41S2yhaJDlQKUQ,5116416
2
+ kfm_cli-0.1.1.dist-info/METADATA,sha256=SrbKFZUEHu4Zwinnh7Gf-_GDMPXCGgJO_Abdp2R07UM,10670
3
+ kfm_cli-0.1.1.dist-info/WHEEL,sha256=Uvw7WSmy7Kj2FBk8Va4L_dq4MDW8X5Ynby-pOX3ZNS0,94
4
+ kfm_cli-0.1.1.dist-info/sboms/kfm-cli.cyclonedx.json,sha256=JNjdIy_3EPQqQF4WLdpL6XYpCzsepPnm9SZAerY75pY,196657
5
+ kfm_cli-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.16.0)
3
+ Root-Is-Purelib: false
4
+ Tag: py3-none-win_amd64