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

  • No window, socket or clock in here: it compiles for wasm. What is specific to one host (the MCP panel, since only the native app has a server) lives in that app.
  • Confidence cannot hold a value outside 0..=1; build one with Confidence::new and handle the None.
  • The pad is laid out in its own coordinates and scaled to the width it is given. Move a button by changing its Part, not the painter calls.
  • Every panel here must survive its value being absent or empty. The bot has no tasks at a menu and no goals before it has seen a screen; say so in the panel rather than drawing an empty one.
  • layout.rs has the layout invariant as a test — equal side panels, an exact 4:3 picture cell, and (since the replay scrubber landed) a scrubber rect spanning the picture's own width, directly between it and the pad. A panel that wants more room asks the app for a different cell; it never widens itself. Run buck2 test //packages/panels:test after anything that touches sizing.
  • replay.rs takes plain data too, the same shape as bot.rs/jev.rs: packages/replay is native-only (it writes files) and this crate compiles for wasm, so nothing from that crate - Tree, BranchMeta, FrameEntry - may appear in this file's public API. The app converts.
  • Colours live in palette.rs and nowhere else. A colour literal in a panel file is a meaning nobody can look up.
  • bot.rs takes plain data, never zbanks types. zbanks links C and is native-only; this crate compiles for wasm.
  • jev.rs takes plain data too, with one deliberate exception: the request sent to Jev stays a serde_json::Value rather than being pre-formatted to a String, so pretty-printing it happens only inside a history row's CollapsingHeader body - which egui calls only while that row is open - instead of on every row on every frame. serde_json has no I/O and already compiles for wasm, so this is not the same kind of exception zbanks/decisions types would be.
  • Keep -Csave-temps=true/-Clink-dead-code in BUCK. They are what let tools/hotpatch/patch.sh fold a panels edit into a hot patch; without them it skips this crate and the patch silently keeps the old panels code.