whiskers.git / tools / README.md
1# tools
2
3| Script | What |
4|---|---|
5| `make-cat.py` | Writes the ginger cat's twelve SVGs from the SVG set it is given. |
6| `make-sounds.py` | Synthesises the poke and dizzy sound effects as WAV files. |
7| `install-android.sh` | Installs the debug APK on a connected device; configured by environment variables, see its header. |
8| `release-apks.sh` | Builds the three release APKs of one calendar version into `~/whiskers-release/<version>/` (see its header). |
9| `run-whiskersd.sh`, `preflight.sh` | Start the service and check everything the app talks to; both take their addresses from the environment or an argument. |
10| `android-sdk.sh`, `android-gradle.sh` | Install the SDK packages at the levels in `mise.toml`; run Gradle in `android/` with the optional `-Pwhiskers.*` taken from `WHISKERS_*` variables. Neither assumes mise or nix: they read `ANDROID_HOME` and `ANDROID_NDK_HOME` and say what is missing. |
11| `with-secrets.sh` | Runs a command under `fnox exec` when fnox is set up, plainly otherwise. |
12| `check-versions.sh` | Fails when a version written outside `mise.toml` (the wasm-bindgen pins, the Gradle build's SDK levels, hk.pkl) differs from it. |
13| `check-private.sh` | Fails if a term from your gitignored `.private-terms` appears in a tracked file. `--message FILE` checks a commit message; `--push` checks every commit that is on no remote yet (files, names, messages), because the whole history is public. |
14| `build-core.sh` | Builds the Rust core for both Android ABIs, generates the Kotlin bindings and writes the grey cat's drawing (`gen-kotlin`); Gradle runs it before every build. |
15
16## Keeping the repository free of private details
17
18Copy nothing personal into a tracked file. To make that checkable, put the terms that must never
19appear (a child's or family member's name, a hostname, an IP address, a device serial, a user
20name, a personal path) one per line in `.private-terms` at the repository root. That file is
21gitignored and must stay out of git: the terms are exactly what the repository must not contain.
22`tools/check-private.sh` greps every tracked file for them (case-insensitive, fixed strings; blank
23lines and `#` comments are ignored) and prints `file:line` for each hit, exiting non-zero. Without
24the file it says so and passes, because there is nothing to check against; `WHISKERS_REQUIRE_PRIVATE_TERMS=1`
25makes a missing file an error. `tools/preflight.sh` runs it, and so does a Rust test
26(`whiskers-core`'s `tests/private_terms.rs`), so `cargo test` catches a regression. It skips the vendored `third-party/pixel-icons` and the icon allowlist, which have to name upstream's icons (a short term matches inside ordinary words there).
27
28## Running them
29
30Every script has a mise task; `mise tasks` lists them, `mise run <task>` runs one, and `mise run <task> -- <arguments>` passes arguments on. The scripts themselves take everything from the environment and work in any shell that has the tools of `mise.toml` on PATH, so they also work inside `nix develop` or a toolchain you installed yourself.
31
32| Task | Script or command |
33|---|---|
34| `core` | `build-core.sh` |
35| `android:debug`, `android:lite`, `android:test`, `android:record-goldens`, `android:verify-goldens` | `android-gradle.sh` with the Gradle task |
36| `android:install`, `android:inspect`, `android:fetch-voices`, `release:apks` | `install-android.sh`, `inspect-apk.sh`, the two `fetch-*.sh`, `release-apks.sh` |
37| `android:sdk` | `android-sdk.sh` |
38| `whiskersd`, `whiskersd:service`, `preflight` | `cargo run`, `run-whiskersd.sh`, `preflight.sh` |
39| `check`, `check-private`, `check-versions`, `check-wasm`, `clippy`, `test` | the fast gates |
40| `dev` | the dev daemons (whiskersd and the website) |
41
42## Git hooks (hk)
43
44`mise run hooks:install` installs the hooks in `hk.pkl`: before a commit `check-private.sh` and `cargo clippy` (warnings are shown, an error-level lint stops it), on the commit message `check-private.sh --message`, before a push `check-private.sh --push` (every unpushed commit, not just the tip) and the website's tests. The tree is not formatted by rustfmt, so formatting is not checked.
45
46## Dev daemons (pitchfork, through mise)
47
48`[daemons]` in `mise.toml` declares whiskersd and the website's `wrangler dev`; mise starts them under pitchfork. `mise run dev` starts both and waits until they answer; `mise daemons status`, `mise daemons logs` and `mise daemons stop` manage them. whiskersd listens on `WHISKERS_ADDR` (default `127.0.0.1:47900`) and needs `WHISKERS_MODEL_URL`.
49
50## Secrets (fnox, optional)
51
52`fnox.toml` declares `TYPESAFE_API_KEY`, `ELEVENLABS_API_KEY`, `ELEVENLABS_VOICE_ID` and `WHISKERS_MODEL_URL` with no value and no provider. Without fnox, export them in the environment before `mise run whiskersd`. To use fnox, put a provider of your own, and the secrets it should resolve, in `fnox.local.toml` (gitignored; a secret defined there replaces the declaration in `fnox.toml`) or in `~/.config/fnox/config.toml`. With 1Password the values stay in the vault and the file holds references:
53
54    [providers.op]
55    type = "1password"
56    vault = "<your vault>"
57
58    [secrets.TYPESAFE_API_KEY]
59    provider = "op"
60    value = "<item>/<field>"
61
62With age the values are stored encrypted for your public key (`age-keygen` makes the pair):
63
64    [providers.age]
65    type = "age"
66    recipients = ["age1..."]
67
68    # then: fnox set TYPESAFE_API_KEY --provider age
69
70`tools/with-secrets.sh` runs the task's command under `fnox exec` when `fnox check` passes, and plainly otherwise (set `WHISKERS_NO_FNOX=1` to force plain). The provider fields are at https://fnox.jdx.dev.
71
72## With nix (optional)
73
74`nix develop` gives a shell with mise and the native tools a downloaded toolchain needs (compiler, pkg-config, OpenSSL, curl, unzip, bzip2); it puts what `mise install` has installed on PATH. The shells `web`, `backend`, `android` and `android-emu` are the same shell. Downloaded programs (the NDK, build tools) are ordinary dynamically linked binaries: NixOS with nix-ld runs them as they are; without nix-ld use `nix develop .#fhs`. The flake also builds the service (`packages.whiskersd`, `whiskersd-static`) and `celld`; it holds no tool version.