whiskers.git / web / CLAUDE.md

For agents, on top of README.md, which they read first.

Notes for agents

  • Datastar with Rust is the standing rule (the owner). Do not add another front-end stack, bundler, or client-side framework. The page's scripts are jev-ui's: Datastar (/datastar.js) and ui.js (the copy buttons and the dot fields), both embedded in the crate and served by this Worker.
  • The look is jev-ui's (~/jevcrates/jev-ui, the submodule at ../third-party/jevcrates): the same as lmjtfy.fun's, by design. Shared presentation goes there, not here; this repository keeps the cat, the demo and the words. Change it in ~/jevcrates and move the pin.
  • What the page says about Jev is read from the code that uses it (site/src/jev.rs, worker/src/explain.rs): whiskers_core::journey, whiskers_judge. Do not write a topic, a threshold or a step into the page by hand. The example responses are hand-written and the page says so; the requests are the guard's own bytes.
  • Follow ~/lmjtfy's conventions (crate layout, a README and CLAUDE.md in every directory, nix devshell). Read, never edit, ~/lmjtfy and ~/nixos-config; a change they need is a proposed patch, written outside this repository.
  • Deploys follow the owner's permission. The owner has allowed redeploying this Worker whenever the site improves (verified first: tests, tools/check-private.sh, regenerated preview); publishing anything else, creating DNS beyond the route in worker/wrangler.toml, or touching another site is still the owner's call.
  • Ginger is the default mascot and first in the picker, then Grey, then Bunny. The link preview's card and video are drawn with the default.
  • The stage is black (cat::stage::STAGE; page.css takes it from there, a test holds them together). A new effect or mascot colour must stand out from it (3 to 1) or lie on a light shape; cat/src/stage.rs's tests fail otherwise. Which mood pill spins is site::demo::pill, the server's word, drawn into every answer; do not bind it in the browser.
  • A mascot is an enum variant with art for every mood. cat::scene is an exhaustive match on Mascot, and each art matches Mood without a wildcard: a new mascot or mood does not compile until it is drawn. Names from a visitor go through Mascot::parse and nothing else; a query value that is not a mascot is the default, a POST that is not one is refused.
  • No family or machine detail on the page, in code, or in comments; say "a young child". Run tools/check-private.sh (repo root) before committing. The page has a test for a few words.
  • The downloads are served by the code host, never by this Worker. "Get it" only links config::RELEASES_URL + a file name (plain links need no CSP directive); the builds are the one table config::APP_DOWNLOADS, a test holds each linked once, and the links may 404 until the code host ships them. Do not proxy or invent other addresses.
  • Nothing is loaded from elsewhere. No CDN, analytics, or third-party image or font (the three faces are jev-ui's own files). A test scans the page and CSS; the CSP forbids it too.
  • Never log a visitor. worker/src/log.rs builds lines only from a route, method, status and time. Do not add a free-text log call in the Worker.
  • One definition of motion (cat/src/motion.rs) serves the page (CSS keyframes) and the video (baked frames). Do not animate anything with hand-written CSS or JS.
  • Toolchain: run everything inside nix develop ~/whiskers#web. The wasm-bindgen pin in Cargo.toml must equal the devshell's CLI version.