llming
CLAUDE.md0 starsChanged 3 months agoMITView on GitHub
This repository holds three unrelated kinds of thing, and the conventions below differ for each: - One-off scripts — small tools solving a single problem, each in its own top-level directory (lookup-mesh-tree-numbers/, calendar-cleanup/). Not worth a repo apiece. Most live on their own unmerged branch, so a top-level directory holding nothing but gitignored files — data/, __pycache__/, an emptied-out tests/ — is a checked-out leftover, not an abandoned tool. Check git branch -a before concluding a tool is missing. -…
In this repository9 other files it gives its agents.
- lookup-mesh-tree-numbers/CLAUDE.mdCLAUDE.md
- settings/CLAUDE.mdCLAUDE.md
- skills/CLAUDE.mdCLAUDE.md
- copilot-reviewSkill
- github-issuesSkill
- github-milestonesSkill
- pr-updateSkill
- sync-docsSkill
- wrapSkill
The file
We split this CLAUDE.md into the rules it gives an agent
10 rules. About 0 are common, 2 are distinctive, and 8 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.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 52
When creating a Python script, create or update both files described above.
- Very specific: line 53
All Python scripts should be runnable with uv run.
- Very specific: line 54
Use click to provide a simple CLI.
- Very specific: line 55
Use logging to provide progress information.
- Very specific: line 56
Use tqdm to provide progress bars and completion estimates on long-running loops.
- Very specific: line 58
When running scripts, use tee to write the output into data/last-run.log.
- Distinctive: line 60
Every script directory gets a README.md covering four things, in this order: what the tool is for, how to run it (a copy-pasteable command …
- Distinctive: line 64
Update it whenever the tool's behaviour or CLI changes.
- Very specific: line 110
Prefer a skill that is only SKILL.md.
- Very specific: line 118
Put it in the skill's scripts/ subdirectory and make it runnable with uv run, declaring any dependencies in a PEP 723 header.
≈ “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
This repository holds three unrelated kinds of thing, and the conventions below differ for each:
- One-off scripts — small tools solving a single problem, each in its own top-level directory
(
lookup-mesh-tree-numbers/,calendar-cleanup/). Not worth a repo apiece. Most live on their own unmerged branch, so a top-level directory holding nothing but gitignored files —data/,__pycache__/, an emptied-outtests/— is a checked-out leftover, not an abandoned tool. Checkgit branch -abefore concluding a tool is missing. - Coding agent skills — everything under
skills/, kept here so it can be shared across machines. These are prose instructions for an agent, not programs. - Settings — config files for the tools I use, under
settings/(settings/README.mdlists them), kept here so a setup that works on one machine can be recreated on another.
Markdown
Run rumdl over any Markdown you are about to commit — every .md file here is linted, and CI
runs the same check on push and pull request:
uv run rumdl check . # what CI runs
uv run rumdl check --fix . # fixes the mechanical ones in place, rewrapping over-long linesConfig lives in pyproject.toml under [tool.rumdl], so the linter and CI agree by construction.
Two settings are deliberate and worth knowing before you fight them:
- Prose wraps at 100, not rumdl's default 80. YAML frontmatter is exempt from the limit
already, which is what a
SKILL.mddescription:needs — it is trigger text for an agent and has to be one line however long it runs. - MD041 is off. It wants every file to open with a level-1 heading; a
CLAUDE.mdorSKILL.mdopens with instructions rather than a title, so the rule never applies here.
Read the diff after --fix: it can break a paragraph without complaint. rumdl reads a wrapped
line that happens to start with # — an issue reference, say — as a heading, although CommonMark
needs a space after the #. --fix then "repairs" it into a real one, splitting the sentence
around a new ## N heading, and a clean re-check hides that anything happened. Reword the sentence
so the # falls mid-line.
README.md and CLAUDE.md
Each kind of thing here is documented by a pair of files, and the split between them is the same in each case.
README.md is the primary documentation, written for a human. It is allowed to get quite long, as
long as what someone needs first is at the top — what this is for, how to run it, what to be
careful about. CLAUDE.md takes the extraneous specifics that would bury that: API response
quirks, the shape of some fallback logic, and above all the gotchas that will save time on the next
visit. The test is roughly when would I want to know this? — before deciding to use the tool at
all, or only once already elbow-deep in the code. Neither file should restate the other.
One-off scripts
When creating a Python script, create or update both files described above.
All Python scripts should be runnable with uv run.
Use click to provide a simple CLI.
Use logging to provide progress information.
Use tqdm to provide progress bars and completion estimates on long-running loops.
Input and output files should be stored in the data/ subdirectory.
When running scripts, use tee to write the output into data/last-run.log.
Every script directory gets a README.md covering four things, in this order: what the tool is for,
how to run it (a copy-pasteable command line), any known issues or limitations to be careful about,
and possible next steps. Write it for someone returning to the tool after six months away — those
four should be readable in a couple of minutes, whatever else the file goes on to say.
Update it whenever the tool's behaviour or CLI changes.
Tests, where a script has them, go in its tests/ subdirectory. pytest is a dev dependency in the
root pyproject.toml, so uv run pytest from the repo root runs everything. Keep test fixtures out
of data/ — that path is gitignored, and anything a test needs has to be committed.
Skills
A skill is a directory under skills/ containing a SKILL.md with YAML frontmatter (name and a
description saying when to use it). The conventions above are for one-off scripts and do not
apply: a skill has no CLI, no data/ directory, and no run log.
Skills do not get a README each — the frontmatter description already covers what the skill
does and when to use it, so a per-skill README would only restate it. Instead there is one shared
skills/README.md recording why each skill exists, what it's for, and where it might go next: the
things a SKILL.md has no room for because it is written for an agent, not for me. Add a section
there when adding a skill.
Name a skill noun-first (pr-update, github-issues), so it groups by subject in the / menu
rather than landing among Claude Code's built-in verbs (/update, /upgrade, /review). The
frontmatter name: sets the command the menu shows, and the name of the entry in
~/.claude/skills/ also invokes the skill. So installing a renamed skill under its old name keeps
that name working as a hidden alias. skills/pr-update/ was installed as update-pr for a while
after its rename, for that reason.
Install a skill onto a machine by symlinking the skill directory into ~/.claude/skills/, not
the SKILL.md inside it (ln -s ~/code/llming/skills/pr-update ~/.claude/skills/pr-update).
Editing through either path is the same file, so a change made on one machine is live everywhere
the directory is linked. Symlinking the SKILL.md alone appears to work and then fails the moment
a skill has anything beside it — the prose arrives, the rest of the directory doesn't, and the
skill's own relative paths resolve to nothing on the machine that needs them.
The symlinks point into this working tree, so the checked-out branch decides which skills are
live, in every session on the machine and not just ones in this repo. Check out a feature branch
and its half-edited SKILL.md is what every agent runs. Check out a branch that predates a skill
and that skill's symlink dangles: the skill drops out of the listing without an error, and comes
back when the branch does. That is handy for trying a skill before it merges, and it is a trap for
anything that measures whether a skill fires — a session run while the skill was absent looks
exactly like one where it failed to trigger. Leave this checkout on the branch you want live, and
do unrelated branch work in a git worktree.
One symlink per skill, because discovery is one level deep: the loader globs
~/.claude/skills/*/SKILL.md, so a directory grouping several skills together is not found and
says nothing about it. Bundling them into one installable unit is a plugin's job — see #32 for the
layout and for when it becomes worth doing.
Prefer a skill that is only SKILL.md. Before adding a helper script, check whether an existing
tool already does the job — gh api graphql --paginate with a --jq filter replaced a 95-line
Python helper in skills/copilot-review/, and npx prettier --prose-wrap never replaced a
110-line Markdown unwrapper in skills/pr-update/. A script that wraps a flag is a script that can
rot, and both of those had already started to: the reimplementation loses on the edge cases the
real tool handles, which for anything file-shaped means silent corruption rather than a crash.
Reach for a script only when nothing installed does the job. If a skill does need one:
- Put it in the skill's
scripts/subdirectory and make it runnable withuv run, declaring any dependencies in a PEP 723 header. Prefer the standard library so there are none. - Reference it by a path relative to the skill directory. Never hardcode an install location like
~/.claude/skills/...— the same skill gets used as a personal, project, and plugin skill. - Skip click, logging, and tqdm. An agent invokes these non-interactively and reads stdout; plain arguments and plain output are easier for it to consume than a CLI framework's.
Settings
Each tool gets a subdirectory of settings/ named after the tool, holding its config files. Like
skills, settings have no CLI, data/ directory, or run log.
Settings are installed by copying, not symlinking, unlike skills. Each machine can then
customise its copy. It also means a shell or editor that starts many times a day doesn't depend on
this checkout: a broken branch, a half-finished rebase or a moved repo would otherwise break every
new terminal. The cost is that copies drift, so settings/CLAUDE.md says how to check them against
the repo.
settings/ has one README.md/CLAUDE.md pair, with a section per tool, like skills/README.md.
A tool with more to say can have its own README.md in its subdirectory instead (settings/vim/),
and settings/README.md then just lists it with a link. The README is written so each setup can be
recreated without the config file. Not every machine uses the same tools, so the README records
the preferences themselves in plain words. The config file is one way of expressing those
preferences. Edits to a machine's startup files (~/.zshrc) are not committed: the README shows the
lines to add instead.
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.

