llming / settings
CLAUDE.md0 starsChanged 3 months agoMITView on GitHub
README.md has the install steps and each tool's settings in words. This file has the specifics. Every machine shares these docs, so don't describe one machine's state ("cloned on this machine", "no JDK here yet"). Say what holds wherever the settings are installed, or leave it out. Settings are installed as copies, so a machine's copy and this repo drift apart. Before changing a tool here, and before committing, diff the two: diff -r oh-my-posh ~/.config/oh-my-posh from settings/, and so…
In this repository9 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- lookup-mesh-tree-numbers/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
4 rules. About 0 are common, 2 are distinctive, and 2 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.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 3
Every machine shares these docs, so don't describe one machine's state ("cloned on this machine", "no JDK here yet").
- Very specific: line 85
All the segments are plain style.
- Distinctive: line 226
Test its edits from the main session.
- Very specific: line 245
Keep glyphs as $'\xNN' byte escapes with the character named in a comment, as in the oh-my-posh 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
README.md has the install steps and each tool's settings in words. This file has the specifics.
Every machine shares these docs, so don't describe one machine's state ("cloned on this machine", "no JDK here yet"). Say what holds wherever the settings are installed, or leave it out.
Checking installed copies against the repo
Settings are installed as copies, so a machine's copy and this repo drift apart. Before changing a tool here, and before committing, diff the two:
| Tool | Repo | Installed copy |
| oh-my-posh | oh-my-posh/ | ~/.config/oh-my-posh/ |
| Vim | vim/vimrc | ~/.vim/vimrc |
| Claude Code | claude-code/statusline.sh | ~/.claude/statusline.sh |
| Claude Code | claude-code/user-CLAUDE.md | ~/.claude/CLAUDE.md |
| Terminal | terminal-app/*.terminal | Terminal's preferences (below) |
diff -r oh-my-posh ~/.config/oh-my-posh from settings/, and so on. For each difference, ask the
user which way it should go: bring the repo's version over, keep the machine's change only on that
machine, or commit it here. This repo is public. Before committing anything from a machine,
read all of it for tokens, hostnames, usernames, home-directory paths, internal tool or project
names, and anything else that shouldn't be published, and remove them. The first copy of the
status line had a comment naming a tool the user hadn't published.
oh-my-posh
The config is oh-my-posh/gaurav-custom.omp.json, installed as a copy in ~/.config/oh-my-posh/,
which is the path ~/.zshrc points at. Editing the repo copy doesn't change the live prompt: copy
it over, or preview it with --config as below.
Previewing a change
Inside a shell that already runs oh-my-posh, oh-my-posh print … --config X silently ignores
--config. A session ($POSH_SESSION_ID) is tied to the first config path it rendered, which is
whatever .zshrc loaded. Edits to that file are picked up at the next prompt, but any other
path is ignored. Drop the session variable to preview a different file:
C="$PWD/oh-my-posh/gaurav-custom.omp.json" # run from settings/
env -u POSH_SESSION_ID oh-my-posh print primary --config "$C" \
--shell zsh --plain -w 100 --execution-time 4200 --status 1
env -u POSH_SESSION_ID oh-my-posh print transient --config "$C" --shell zsh --plain --status 1--execution-time is in milliseconds. --plain removes the ANSI colours so the output can be read
as text. A JSON syntax error doesn't fail: it exits 0 and renders the default theme with a
CONFIG PARSE ERROR segment, which is easy to miss in a real terminal.
print can't show how prompts behave over time: the transient collapse, the blank line, the
cursor-position query. To check those without a human at a terminal, run zsh -i under Python's
pty.fork() and feed its output into a pyte screen (pip-install pyte into a throwaway venv).
Answer the query by setting screen.write_process_input to write back to the pty. Type commands
with os.write(fd, b"cmd\r"), wait a few seconds, and print screen.display.
The blank line comes from "newline": true on the first block. enable_cursor_positioning keeps it
off the top of a fresh window. It asks the terminal where the cursor is, and skips the newline in
column 0 of row 0. The transient prompt redraws from the start of the prompt, so the blank line
goes with it.
Editing the JSON
- Keep glyphs as
\uXXXXescapes. Nerd Font icons are private-use code points that most editors (and diffs) show as blanks. Some tools, including agent file-writing tools, write the raw characters even when given escapes. Re-serialise afterwards withjson.dumps(config, indent=2, ensure_ascii=True). - The schema for the installed version is local, at
/opt/homebrew/opt/oh-my-posh/themes/schema.json, and outranks remembered examples: config version 4 calls segment settingsoptions(older themes online sayproperties), and the git segment has nofetch_statusany more. It fetches status whenever the template uses it. - The bundled
powerlevel10k_*.omp.jsonthemes in the same directory were the starting point.powerlevel10k_classichas the colours but no duration, filler, frame or transient prompt.
How the layout works
- Every colour is a palette reference (
p:role). There are no hex values in the blocks.palettes.listholds the named palettes, andpalettes.templatepicks one from$POSH_PALETTE, falling back to the default. Top-levelpaletteis a copy of the default, used when$POSH_PALETTEnames a palette that doesn't exist. To add a palette, fill every role, and check contrast against both the bar and black (the frame, dots and▶sit on the terminal background).preview-palettes.zshreads the palette names from the JSON. - The prompt is three blocks: left-aligned line 1, right-aligned line 1 (which carries the
fillerdots, which only work on a right-aligned block), and a"newline": trueblock for line 2.transient_promptis a top-level key, not a block. - All the segments are
plainstyle. The coloured bar comes from a sharedbackground, with the arrows and frame drawn bytextsegments on a transparent background. Powerline style would put an arrow between every pair of segments. p10k classic uses thin separators within a group instead. - On the right,
executiontimeis first and always renders (always_enabled, threshold 0), and every segment after it starts with its own leading\u2039(‹) separator. That way a hidden segment never leaves a doubled or dangling separator. Anything placed beforeexecutiontime, or a change that lets it hide, breaks this. - The "took …, finished …" wording is decided in the template (
if ge .Ms 3000), not by the segment'sthreshold. The finish time is sprig'snow, which works inside any template, and Go's3:04:05pmlayout. executiontimeuses"style": "austin":450ms,4.2s,2m 10s,1h 2m 5s. To compare the other styles, render each one at a few--execution-timevalues. The names don't tell you much.statusappears twice. On the right it has the defaultalways_enabled: false, so it only renders after a failure. On line 2 it hasalways_enabled: trueand exists to colour the▶throughforeground_templates.- The right-aligned block has
"overflow": "hide". Without it, a line 1 that doesn't fit spills the right side onto a wrapped line. - In the git segment,
.Staging.Changedand.Working.Changeddon't mean a count is nonzero. A merge conflict sets both, but oh-my-posh counts it only in.Staging.Unmergedand.Working.Unmerged(one per file in each), not inAdded/Modified. Guarding onChangedprinted+0during a merge, so each count is guarded on its own sum instead..Working.Addedis a file added withgit add -N, counted under!. To see what oh-my-posh reports for a repo state, render a throwaway config whose git template prints every field. - The path uses
"style": "powerlevel"withmax_width30.right_formatbolds and colours the last folder. Thedisplay_rootoption is off, so outside~, the leading/is dropped (o/h/C/…). - The language segments use
display_mode: files, so they only run in project folders. Python hasfetch_virtual_env: false, because I don't want the venv name shown.
Shell side
ZSH_THEME is empty, because oh-my-posh now draws the prompt in every terminal, Terminal.app
included. Leaving an Oh My Zsh theme set makes both set up a prompt, and oh-my-posh's overwrites
the other. oh-my-posh init zsh reads transient_prompt from the config and installs its zle
hook itself, so no extra zsh code is needed for the transient prompt.
Terminal.app
The profile lives in ~/Library/Preferences/com.apple.Terminal.plist under Window Settings.
The .terminal file here is that one dictionary, extracted as it is:
plutil -extract "Window Settings.Solarized Darker" xml1 \
-o "terminal-app/Solarized Darker.terminal" ~/Library/Preferences/com.apple.Terminal.plistRe-export after every change and commit it. Colours and the font are keyed archives stored as
base64 <data>, so a diff of the file shows nothing readable. To see what changed, decode it with
plistlib: each colour's archive has an NSRGB string of 0–1 floats.
Change the profile through AppleScript while Terminal is running, not by editing the plist behind its back. Terminal keeps its profiles in memory and may write them back over the edit. AppleScript changes save straight away:
osascript -e 'tell application "Terminal"' \
-e 'set number of columns of settings set "Solarized Darker" to 120' -e 'end tell'The scriptable properties are the window size, font name and size, antialiasing, and the cursor,
background, normal text and bold text colours (as 16-bit {r, g, b}). The 16 ANSI colours and
the selection colour are not scriptable. Change those in Terminal ▸ Settings, or quit Terminal
and round-trip the whole domain through defaults: defaults export com.apple.Terminal x.plist,
edit the colour archive's NSRGB string with plistlib, then defaults import com.apple.Terminal
x.plist. That goes through the preferences daemon (cfprefsd), whereas writing
~/Library/Preferences/com.apple.Terminal.plist directly can be undone by its cached copy.
To make a new profile from an existing one without quitting Terminal:
- Copy the
.terminaldict in Python. - Swap colours by cloning an existing colour archive and replacing its
NSRGBstring. - Change
name. openthe file. Terminal imports it (and opens a window with it).- Make it the default with AppleScript
(
set default settings to settings set "…", and the same forstartup settings). - Re-export Terminal's stored copy over the file. Terminal re-encodes the archives on import, so the bytes change but the values don't.
That's how Tokyo Night Darker was made from Solarized Darker.
Vim
~/.vim/vimrc is only read when ~/.vimrc doesn't exist. If an edit to ~/.vim/vimrc has no
effect, look for a stray ~/.vimrc first. :echo $MYVIMRC names the file Vim loaded.
If Vim acts as if defaults.vim never ran (scrolloff=0, no restore-cursor, no incsearch),
skip_defaults_vim is set. macOS's system vimrc (/usr/share/vim/vimrc) sets it, and
defaults.vim quietly does nothing, so the unlet! has to come before the source.
:scriptnames shows whether defaults.vim was loaded at all. Homebrew's Vim has no system vimrc,
so a vimrc that works there can still fail in /usr/bin/vim, which is what git commit often
opens. Check both.
To check the vimrc without a human at a terminal, copy it into a throwaway $HOME under
data/ and run Vim under a pty, writing options to a file:
H=$PWD/data/vim-check/home # with the vimrc copied to $H/.vim/vimrc
HOME=$H TERM=tmux-256color script -q /dev/null /usr/bin/vim \
-c "redir! > $H/out.txt | silent set mouse? ttymouse? scrolloff? | redir END | qa!" </dev/nullvim -es won't do: silent Ex mode skips the vimrc. Vary TERM, because defaults.vim and Vim's
own ttymouse detection both branch on it.
Claude Code
claude-code/statusline.sh is installed as a copy at ~/.claude/statusline.sh, which is where
/statusline and its agent edit it. Changes made that way have to be copied back here, which is
the main way this one drifts. Claude Code runs it after each message, passing a JSON payload on
stdin.
The status line docs list its fields; the ones used
here are workspace.current_dir, context_window.used_percentage and .total_input_tokens,
rate_limits.{five_hour,seven_day}.{used_percentage,resets_at} (resets_at in epoch seconds),
model.display_name and effort.level.
Test with a fake payload, not by waiting for Claude Code to redraw:
N=$(date +%s)
jq -n --argjson now "$N" '{workspace: {current_dir: "'"$PWD"'"},
context_window: {used_percentage: 42, total_input_tokens: 84000},
rate_limits: {five_hour: {used_percentage: 4, resets_at: ($now + 13920)},
seven_day: {used_percentage: 20, resets_at: ($now + 277200)}},
model: {display_name: "Opus 5.5"}, effort: {level: "high"}}' \
| bash claude-code/statusline.sh | cat -vAlso try a quota with no resets_at (five_hour: {used_percentage: 4}). The docs say Claude Code
sends both fields or drops the window, but the script is meant to show just the percentage, not
until (now). Likewise try a context window with no total_input_tokens, a zero one, or one
small enough to round to 0k (total_input_tokens: 400): each should show ctx 42%, not
ctx 0k (42%).
cat -v shows the escape codes, which is the only way to check colours without a human looking.
Strip them with perl -pe 's/\e\[[0-9;]*m//g' to read the text. For git states, make throwaway
repos (a bare remote plus clones that are clean, dirty, ahead and behind) and point
current_dir at each.
The statusline-setup agent that /statusline launches has no shell, so it can't run the script.
Test its edits from the main session.
Don't rename user-CLAUDE.md to CLAUDE.md, although that is its installed name. Claude Code
loads a file called CLAUDE.md from any directory it reads files in, so under that name it would
become instructions for every agent working in claude-code/ rather than a file they're editing.
Colours and glyphs
- Solarized's bright ANSI colours are mostly greys (bright green, yellow and blue) or other hues (bright red is orange, bright magenta is violet). Only bright white is a brighter version of its base colour. Use 24-bit colour for a lighter tint instead.
- Don't brighten with bold. The profile has
UseBrightBoldandUseBoldFontsoff, so bold does nothing visible in Terminal.app, and a terminal with bright-bold on would shift the hue. - Check a glyph's vertical position before using it. Many geometric shapes (
◆,●,■,▰) sit well below the middle of capital letters in Meslo.♦,•and◦are centred. Measure with fontTools:uv run --with fonttools python→ load~/Library/Fonts/MesloLGMNerdFont-Regular.ttf, draw the glyph into aBoundsPen, and compare its vertical centre withH's. A glyph missing from the font renders from a fallback font, at whatever size and height that font uses. - Keep glyphs as
$'\xNN'byte escapes with the character named in a comment, as in the oh-my-posh 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.

