windvane
CLAUDE.md0 starsChanged 36 days agoMITView on GitHub
A Claude Code plugin that keeps the state of a session and steers it: the recorder drafts the checkpoint, compaction happens at the right point with the state banked, the rules and the checkpoint ride inside the compacted conversation and every subagent's prompt, tool results are trimmed and secrets redacted, and project memory and rules are a tool call away. The principle: never ask the model to write what the machine can record. This file is for people working on…
In this repositoryOne other file it gives its agents.
- referenceSkill
The file
We split this CLAUDE.md into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 25
Run the tests for the module you changed, not the whole suite by default.
- Very specific: line 43
Never write a file with a call that turns line endings into CRLF.
- Distinctive: line 50
Every claim in a doc is backed by code in this tree.
- Distinctive: line 51
Do not describe internal function names in user docs.
- Very specific: line 53
Keep user-visible numbers (defaults, thresholds, counts) in step with config.py, rules.py and hooks.json.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
windvane
A Claude Code plugin that keeps the state of a session and steers it: the recorder drafts the checkpoint, compaction happens at the right point with the state banked, the rules and the checkpoint ride inside the compacted conversation and every subagent's prompt, tool results are trimmed and secrets redacted, and project memory and rules are a tool call away. The principle: never ask the model to write what the machine can record.
This file is for people working on windvane itself. Users read README.md and docs/.
Layout
.claude-plugin/plugin.jsonis the manifest and holds the config rows.marketplace.jsonmakes the repository its own marketplace.hooks/is the mod, in TypeScript.register.tsregisters every hook and is the only file that holds$; the pieces keep their logic in their own modules and take aHostof closures (engine.ts): the band, the pane,/remember, the strict, export and import commands, the door, the ledger, the agent briefs, the compaction brief, the bridge, the tools and the first-run offer of the semantic tier (setup.ts).hooks.jsondeclares the classic command hooks used headless and as the bridge's fallback. The mod's tests aretests/mod/*.test.ts.windvane/is the Python engine. No dependencies.events/there holds the hook handlers,mining/the session miner,semantic/the optional encoder.daemon.pyanddaemon_client.pyare the resident process and its thin client.config.pyholds every setting inKNOBS.skills/reference/SKILL.mdis the quick reference the model reads (/windvane:reference; the plain/windvaneis the pane, so the skill cannot share that name).docs/is the user documentation.docs/assets/holds the logo marks, the social card (uploaded in the repository's settings, nothing links it) and the two SVG diagrams the README and how-it-works embed; the diagrams use only neutral greys and the accent so they read on GitHub's light and dark themes.demo/holds the demo tapes and gif.tests/holds the Python tests.types/and.claude-plugin/types/are the type declarations for the mod. The second folder is written by Claude Code when the plugin loads and is not committed.
Tests
Python tests, from the repository root (needs pytest, available as the test extra):
python -m pytest tests/test_config.pyRun the tests for the module you changed, not the whole suite by default. pyproject.toml puts the repository root on the path, so windvane imports from the tree.
The installed plugin on a development machine is usually this folder. A change that moves or renames windvane/daemon_client.py, or the commands in hooks/hooks.json that name it, breaks every hook of the running session the moment it lands: fix hooks.json first, run /reload-plugins, then move the file.
Plugin tests and checks, from the repository root:
claude plugin test .
claude plugin validate .Python needs 3.10 or later.
Rules for the code
- The engine stays standard-library only. The semantic tier is an optional extra and is imported only inside the functions that need it.
- Every
on(...)lives inregister.ts, with the hook's body written there, and$is passed only to functions declared at the top of that file (the plugin directory's reader refuses$oronhanded to another file). The other modules take aHost(engine.ts) built byhostOfinregister.ts, where every$.noun.methodcall and every environment variable name is spelled; the$.statereferences are declared inregister.tsand the drawings get plain values. The engine takes one unmatched hook per event per plugin. No hook sits on a pattern (*,tool.*,classic.*): the classic events are hooked by name, andPreToolUsehas no mod hook at all, because the directory reads a permission check's hook only when it returns a literal{ deny }or{ ask }ornext(e)witheread plainly (a member, or handed whole to a function, never through a cast); atool.callhook answers that way or with{ result }. Keep that shape. register.tsmirrors the engine's pressure constants (output reserve, checkpoint margin, heads-up fraction, default compaction point). Change both together.- Never write a file with a call that turns line endings into CRLF. The repository is LF, and
.gitattributesnormalises on read, so a CRLF file looks clean ingit statuswhile its bytes differ. Write bytes with the terminator the file already has. - A hook handler must never raise into Claude Code. Failures degrade to an empty answer.
- The mod writes nothing to the store. The engine writes it.
Rules for text
- Docs and comments are plain prose for a stranger: no personal names, machine names, workspace paths, email addresses or network addresses, and no emoji.
- Every claim in a doc is backed by code in this tree. When a doc and the code disagree, the code wins and the doc is fixed.
- Do not describe internal function names in user docs.
- Commits and published text carry no personal names.
- Keep user-visible numbers (defaults, thresholds, counts) in step with
config.py,rules.pyandhooks.json.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

