The derivation landed in decision 0018 with the catalog and the terminal ANSI palette still fixed tables written by hand. tools/theme-gen reads the TextMate themes under assets/themes/ and emits the catalog and the reference vectors, so the anchors a palette is derived from are the ones the theme actually ships rather than the ones somebody transcribed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SPYebLiN2w4TqnHUYGdECq
2.8 KiB
theme-gen
Turns the theme files vendored in assets/themes/ into
crates/lumbridge-theme/src/generated/catalog.rs and
assets/themes/NOTICE-THEMES.md.
cargo run -p theme-gen # rewrite both files
cargo run -p theme-gen -- --check # fail if either is out of date
Dev-only. Nothing in the workspace depends on it at build time, and --check is
the hook a future CI step would use.
Why it is a binary and not a build.rs
Two reasons, in order of weight.
The colours a user sees should be reviewable as text in a pull request. If an
upstream theme changes a hex digit, that should arrive as a diff someone reads,
not as a silently different build. Everything this tool produces is checked in
for exactly that reason, and --check is what keeps the checked-in copy honest.
And a build that reads assets/themes/ makes the asset tree a build input.
Trimming assets in a packaging step would then break compilation rather than
breaking a theme picker, which is the wrong failure.
What it decides, and what it only measures
The tool makes no aesthetic choices. It applies rules and records what they produced:
- Anchors.
editor.background,editor.foreground, the comment token's foreground, and the git-decoration colours, by the rules insrc/extract.rs. - Terminal palette. The theme's
terminal.ansi*keys where it has them, a syntax token that stands for the same role where it does not, and a documented hue derived from the theme's own foreground where it has neither. - Contrast gate. A theme whose body text measures below 4.5:1 against the surface Lumbridge derives for it is held back, and the measurement is written into the generated file's header. Three themes currently fail.
- Distinctness. Two escape codes that would paint the same colour, and two role colours that would make decision 0012's provenance shades identical, are forced apart — and every such substitution is written down twice: as a comment above the theme, and in a machine-readable constant the tests read back.
Licence exclusion happens before this tool, at the vendoring step, so a GPL
theme is never in the tree at all. See assets/themes/SOURCE.md.
reference/
reference/emit-reference-vectors.mjs regenerates
crates/lumbridge-theme/src/generated/reference_vectors.rs by running Buzz's
original TypeScript under Node over the same vendored theme files. It needs the
Buzz checkout, which lives outside this repository and is pinned in
docs/RESEARCH_SNAPSHOTS.md, so it is not a step CI can run — which is why its
output is checked in and the test that reads it runs everywhere.
Run it only when the derivation itself changes. Decision 0018 explains at some length why these vectors must come from running the original and never from re-deriving them.