1# The toolchain, the environment and the tasks of this repository: the one place 2# every tool version lives. Nothing here needs nix, nix-darwin or root: 3# 4# mise trust && mise install the toolchain (a C compiler and git must exist) 5# mise tasks what can be run 6# mise run check the fast gates 7# mise run dev the Worker under wrangler dev, supervised by pitchfork 8# 9# `tools/check-versions.sh` (part of `mise run check`) fails when a version 10# written elsewhere (Cargo.toml's wasm-bindgen pin, hk.pkl's hk release) differs 11# from the one here. The nix flake only wraps this file; it holds no version of its own. 12min_version = "2026.10.0" 13 14[settings] 15# `[daemons]` below needs it. 16experimental = true 17 18[tools] 19# The Worker is Rust compiled to WebAssembly. 20rust = { version = "1.99.0", profile = "minimal", components = "rustfmt,clippy", targets = "wasm32-unknown-unknown" } 21# The wasm-bindgen CLI must equal the `wasm-bindgen` crate pinned in Cargo.toml 22# (checked by tools/check-versions.sh). worker-build downloads wasm-opt and esbuild itself. 23"cargo:wasm-bindgen-cli" = "0.2.127" 24# worker-build links OpenSSL on Linux. A system copy (and pkg-config) is not assumed: the same OpenSSL from 25# conda-forge is installed first and linked from where mise put it. 26"conda:openssl" = "3.5.9" 27"cargo:worker-build" = { version = "0.8.6", depends = ["conda:openssl"], install_env = { OPENSSL_DIR = "{{ env.MISE_DATA_DIR | default(value=xdg_data_home ~ '/mise') }}/installs/conda-openssl/3.5.9", RUSTFLAGS = "-C link-arg=-Wl,-rpath,{{ env.MISE_DATA_DIR | default(value=xdg_data_home ~ '/mise') }}/installs/conda-openssl/3.5.9/lib" } } 28 29# wrangler runs the Worker locally and deploys it. 30node = "24.20.0" 31"npm:wrangler" = "4.129.0" 32 33# The jdx tools: git hooks, supervised dev daemons, secrets. 34hk = "2.5.0" 35pkl = "0.32.1" 36pitchfork = "2.29.0" 37fnox = "1.36.0" 38 39[env] 40WRANGLER_SEND_METRICS = "false" 41 42# What the owner's tasks read, never written here. Declared, without values, in fnox.toml; 43# tools/with-secrets.sh puts them in a command's environment through fnox when it is set up, 44# and a command simply finds them in the environment otherwise. 45# CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID wrangler (Workers AI has no local emulation) 46# LMJTFY_TYPESAFE_API_KEY the Jev key, for the dev server 47# LMJTFY_GITHUB_TOKEN the clone proxy's read-only token 48 49# ---------------------------------------------------------------- setup 50 51[tasks.submodules] 52description = "Fetch the git submodules (third-party/jevcrates and the pictures)" 53run = "git submodule update --init --recursive" 54 55[tasks."hooks:install"] 56description = "Install the git hooks (hk.pkl): clippy before a commit, the tests before a push" 57run = "hk install" 58 59# ---------------------------------------------------------------- checks 60 61[tasks."check-versions"] 62description = "Fail if a version written outside mise.toml differs from it" 63run = "tools/check-versions.sh" 64 65# The tree is not formatted by rustfmt, so formatting is not checked. Warnings are shown, not fatal. 66[tasks.clippy] 67description = "cargo clippy over the workspace (warnings are shown, an error-level lint fails)" 68run = "cargo clippy --workspace --all-targets" 69 70[tasks.test] 71description = "Everything but the Worker's I/O, natively (cargo test --workspace --lib)" 72run = "cargo test --workspace --lib" 73 74[tasks.check] 75description = "The fast gates: versions and the tests" 76depends = ["check-versions", "test"] 77 78# ---------------------------------------------------------------- build and run 79 80[tasks.build] 81description = "Build the Worker for WebAssembly into apps/lmjtfy/build (worker-build --release)" 82dir = "apps/lmjtfy" 83run = "worker-build --release" 84 85[tasks."dev:preflight"] 86description = "Fail at once, with the reason, if the Cloudflare credentials the dev server needs are missing" 87run = "tools/with-secrets.sh tools/wrangler --preflight" 88 89[tasks.dev] 90description = "Start the dev server (http://localhost:8787/) under pitchfork and wait until it answers" 91depends = ["dev:preflight"] 92run = ["mise daemons start worker", "echo 'the Worker is on http://localhost:8787/; mise daemons logs worker, mise daemons stop worker'"] 93 94# ---------------------------------------------------------------- the owner's tasks 95# These need the owner's Cloudflare account: CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in the 96# environment (or in fnox, see fnox.toml). Anyone else can deploy their own copy the same way. 97 98[tasks."deploy-staging"] 99description = "OWNER: deploy the staging Worker (https://staging.lmjtfy.fun, behind the owner's login)" 100run = ["mise daemons stop worker", "tools/with-secrets.sh tools/wrangler deploy --env staging"] 101 102[tasks.deploy] 103description = "OWNER: deploy the site and code.lmjtfy.fun (extra arguments go to wrangler: -- --var GIT_REDIRECT:off rolls the redirect back)" 104run = ["mise daemons stop worker", "tools/with-secrets.sh tools/wrangler deploy"] 105 106# ---------------------------------------------------------------- daemons 107 108# Supervised by pitchfork, started and stopped through mise. wrangler rebuilds the Worker itself when a 109# source changes; its watcher can start two builds off one save, which collide in build/ and take wrangler 110# down (2026-10-02). tools/wrangler-dev reports any exit pitchfork did not ask for as a failure, and 111# `retry` starts it again (five times, then `mise run dev` fails instead of waiting for ever). 112[daemons.worker] 113run = "exec tools/with-secrets.sh tools/wrangler-dev" 114ready_http = { url = "http://127.0.0.1:8787/", timeout = "10m" } 115retry = 5