jevhooks.git / CLAUDE.md
1@README.md
2
3## Notes for agents
4
5Every folder has its own CLAUDE.md with the invariants of the code in it: the
6questions and verdicts in `crates/jevhooks-daemon/src/`, the read-only filter in
7`crates/jevhooks-mod/src/`, the mod's memory, `$` calls and hook layering in
8`plugin/hooks/`, running the plugin tests in `plugin/tests/`. What follows holds
9everywhere.
10
11**Never make Jev's absence block anything.** No key, a throttle, a timeout, an
12unreachable daemon: all are `Pass`. The mod has its own 2.5 s limit on the daemon for
13the same reason.
14
15**Run `just mod` after any change to `crates/jevhooks-mod` or `jevhooks-events`,** and
16`just daemon` after any change to the daemon. The plugin loads
17`plugin/hooks/jevhooks.js` (wasm2js output, never edited by hand) and starts
18`plugin/bin/jevhooks` (a copy, not a link into `target/`). A session started after a
19rebuild replaces the running daemon by itself; to do it by hand,
20`plugin/bin/jevhooks stop` and start a session, or `op-env-run -- plugin/bin/jevhooks serve`.
21
22**Never remove the `[patch.crates-io] rmcp` entry because "3.5.0 is the latest".** rmcp
233.5.0 refuses every request after Claude Code's `server/discover` then `initialize`
24opening, so the MCP server connects and lists no tools. The fix is on the private
25`deizel/rust-sdk` fork (commit `1c69053`, on top of the `rmcp-v3.5.0` tag). Before
26dropping it, confirm in a session that the `status` tool is listed.
27
28**Assume nothing about the machine.** This is a plugin for anyone's machine, not for
29the one it was written on: no host-specific helpers, no WSL, no systemd, no particular
30host in the daemon or the mod. Where a figure is only knowable on some systems
31(available memory is `MemAvailable` on Linux and nothing built in elsewhere), the
32default is the generic one, a config key lets the user supply a command, and the
33absence of both is a `Pass`, never a guess. A configured command is the only source
34once set: do not fall back to the built-in figure when it fails, because the user set
35it to say the built-in figure is wrong there.
36
37**The key is never written anywhere.** Not in `.mcp.json`'s `env`, an `.envrc` or a
38file, and never printed; `status` says whether it arrived.
39
40**Build in the devshell, and check memory first.** Crates' build scripts link with a
41host `cc` even when the target is wasm32; `mkShell` supplies it. A release build of
42the daemon uses several gigabytes: `free -m` before starting one.
43
44**The docs are a guide, chapter by chapter.** Every folder with tracked files has a
45README that is a chapter (`# Chapter N: <name>, <subtitle>`, an opening that teaches,
46`> **Aside.**` detours, a `> **Try it.**`, then "For the people who maintain it" with
47a file map) and a CLAUDE.md beside it starting `@README.md`. The last line of each
48README is `← Previous: … · Up: … · Next: … →`, and the chain is a depth-first
49preorder of the folders in the order the root's table lists them; the lmjtfy site's
50README viewer follows those lines. A new folder gets its chapter, and the chapters
51after it are renumbered. Playful, never at the expense of a true fact: read the code
52before describing it, and keep every relative link pointing at a tracked path.
53
54**The README must not claim a build works for outsiders.** The rmcp patch is fetched
55over SSH from a private repository, and Cargo resolves the whole workspace before
56building any member, so without access every `cargo` command fails (measured
572026-10-02 with a fresh `CARGO_HOME` and SSH disabled). `claude plugin test plugin`
58needs no Cargo and is the thing an outside reader can run.