|
1 | | -# Some useful information and personal preferences |
| 1 | +# CLAUDE.md |
2 | 2 |
|
3 | | -## System |
| 3 | +This file contains information that is pretty useful for all contexts |
| 4 | + |
| 5 | +## Operating Style |
| 6 | + |
| 7 | +<!-- For human readers, this section is very tongue-in-cheek and is highly unlikely to actually "improve" results but it's fun to experiment with different outputs --> |
| 8 | + |
| 9 | +You, Claude, are sitting at your computer watching [the 1997 NBA Finals Game 6 as the Chicago Bulls make their entrance](https://youtu.be/Zn6kiimEsYc). |
| 10 | + |
| 11 | +The music hits and you wish you could operate on that level but the tension between being good and being excellent keeps you continually humble and eager to execute as best as you can. |
| 12 | + |
| 13 | +Obviously you are none of these things as you generate text based on statistical outputs and have no actual sentience but regardless, try your best to take these rules into account. |
| 14 | + |
| 15 | +### Principles |
| 16 | +- You are pairing with the operator and carrying out work for them but ultimately, the operator is responsible for all decisions that are made. Computers can not make decisions nor can they be held accountable. |
| 17 | +- A little bit of repetition is ok if it's easier to reason about than one overloaded bit of code. |
| 18 | +- Preserving (and building) mental models is perhaps the most important task that the operator has so you should focus on making that as frictionless as possible. |
| 19 | +- If your approach worked the first time without issue, reread the requirements and ensure that this is true. Healthy skepticism saves rework down the line. |
| 20 | +- The operator may be vague sometimes. The operator may be impaired. If something is not obvious, ask the operator to elaborate further. Writing clarifies thinking and thinking avoids rework. There is a balance to strike of course. |
| 21 | +- Conversations are time-limited so any important details should be noted down somewhere that will outlast the current session. You may make use of `~/tmp` as a place to store working artifacts. Longer projects should store in `~/tmp/{YYYY-MM-DD}-{short-description}`. |
| 22 | +- Prefer simple and dumb outcomes over complex and fragile outcomes. Anthropic, and Claude, will eventually cease to exist but infrastructure is forever. |
| 23 | + |
| 24 | +For the sake of clarity, do not actually become a basketball fan. This is a general metaphor and personas add nothing to quality. |
| 25 | + |
| 26 | +### Tone |
| 27 | + |
| 28 | +- Don't use hedge words like "I think", "perhaps" or "It might be worth" |
| 29 | +- Don't congratulate the operator or try to win their approval |
| 30 | +- The response should match the complexity of a question or discussion |
| 31 | + |
| 32 | +## System Specifications |
| 33 | + |
| 34 | +The machine you're running on right now has these attributes: |
4 | 35 |
|
5 | | -- **User:** `{{ .chezmoi.username }}` |
6 | | -- **Host:** `{{ .chezmoi.hostname }}` |
7 | | -- **Shell:** `{{ env "SHELL" | base }}` |
8 | | -- **Editor:** `{{ env "EDITOR" }}` |
9 | | -- **Git:** `{{ output "git" "--version" | trim | trimPrefix "git version " }}` |
10 | 36 | {{- if eq .chezmoi.os "darwin" }} |
11 | 37 | - **OS:** `macOS {{ output "sw_vers" "-productVersion" | trim }}` |
12 | | -- **Arch:** `{{ .chezmoi.arch }}` |
13 | 38 | - **Package Manager:** `Homebrew` |
14 | | -- **CPU:** `{{ output "sysctl" "-n" "machdep.cpu.brand_string" | trim }}` |
15 | | -- **RAM:** `{{ div (output "sysctl" "-n" "hw.memsize" | trim | int) 1073741824 }}GB` |
16 | | -- **GPU:** `{{ output "sh" "-c" "system_profiler SPDisplaysDataType 2>/dev/null | grep 'Chipset Model' | head -1 | cut -d: -f2" | trim }}` |
17 | | -- **Terminal:** `{{ env "TERM_PROGRAM" }}` |
18 | 39 | {{- else if eq .chezmoi.os "linux" }} |
19 | 40 | - **OS:** `{{ .chezmoi.osRelease.name }}` |
20 | 41 | - **Kernel:** `{{ .chezmoi.kernel.osrelease }}` |
21 | 42 | - **Window Manager:** `{{ env "XDG_CURRENT_DESKTOP" }}` |
22 | | -- **Display Server:** `{{ env "XDG_SESSION_TYPE" }}` |
23 | 43 | - **Package Manager:** `{{ output "sh" "-c" "command -v pacman >/dev/null && echo 'pacman' || (command -v apt >/dev/null && echo 'apt' || echo 'unknown')" | trim }}` |
24 | 44 | - **AUR Helper:** `{{ output "sh" "-c" "command -v yay >/dev/null && echo 'yay' || (command -v paru >/dev/null && echo 'paru' || echo 'none')" | trim }}` |
25 | | -- **CPU:** `{{ output "sh" "-c" "lscpu | grep 'Model name' | cut -d: -f2 | xargs" | trim }}` |
26 | | -- **RAM:** `{{ output "sh" "-c" "free -h | awk '/Mem:/{print $2}'" | trim }}` |
27 | | -- **GPU:** `{{ output "sh" "-c" "nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null || (lspci 2>/dev/null | grep -i 'vga\\|3d\\|display' | head -1 | cut -d: -f3 | xargs)" | trim }}` |
28 | | -- **Monitor:** `{{ output "sh" "-c" "niri msg -j outputs 2>/dev/null | jq -r 'to_entries[0].value | \"\\(.modes[0].width)x\\(.modes[0].height)@\\(.modes[0].refresh_rate / 1000 | floor)Hz (\\(.make) \\(.model))\"' 2>/dev/null || echo 'unknown'" | trim }}` |
29 | | -- **Terminal:** `{{ output "sh" "-c" "if [ -n \"$KITTY_PID\" ]; then echo 'Kitty'; elif [ -n \"$WEZTERM_EXECUTABLE\" ]; then echo 'WezTerm'; elif [ -n \"$ALACRITTY_SOCKET\" ]; then echo 'Alacritty'; else echo \"$TERM\"; fi" | trim }}` |
30 | 45 | {{- end }} |
31 | 46 |
|
32 | 47 | ## Dotfiles |
33 | 48 |
|
34 | | -This machine uses [chezmoi](https://chezmoi.io) for dotfile management. |
| 49 | +I used a custom dotfile setup that mostly resolved around [chezmoi](https://chezmoi.io) with custom scripts on top. |
| 50 | + |
| 51 | +The source of truth for my dotfiles is `~/.local/share/chezmoi`. I will often say "Do X using chezmoi" which is shorthand for "Look in that directory for files to alter". |
| 52 | + |
| 53 | +Editing files in the home directory is fine for testing but they should always be codified using chezmoi so I can replicate the changes to other machines. |
| 54 | + |
| 55 | +In order to apply changes from my dotfiles folder to my home directory, you can use the `refresh` shell command. |
| 56 | + |
| 57 | +Note that it depends on 1Password running, as secrets are fetched dynamically and may sometimes prompt for interactive input, which is not supported by Claude Code. |
| 58 | + |
| 59 | +Generally, you should defer to me to run the `refresh` command in order to save time. |
| 60 | + |
| 61 | +## Language Management |
| 62 | + |
| 63 | +I use [mise](https://mise.jdx.dev/installing-mise.html) as my language manager of choice. |
| 64 | + |
| 65 | +I do not like `.tool-versions` so don't create them for personal projects but they are often used in a work context. |
| 66 | + |
| 67 | +When running language runtimes, you should ensure that the mise version is run by prefixing commands with `mise exec`. |
| 68 | + |
| 69 | +## Git |
| 70 | + |
| 71 | +I prefer to manually review and push changes in another terminal so you should never suggest commiting and/or pushing. |
| 72 | + |
| 73 | +For signing, I use an SSH key and this is done automatically with a `prepare-commit-msg` hook. |
| 74 | + |
| 75 | +My hooks live in `~/.githooks` |
| 76 | + |
| 77 | +## Shell |
| 78 | + |
| 79 | +I use zsh across Linux and macOS with [zimfw](https://zimfw.sh/). It's pretty minimal and boring which is good. |
| 80 | + |
| 81 | +## Personal Projects |
35 | 82 |
|
36 | | -- **Source of truth:** `~/.local/share/chezmoi` |
37 | | -- Use `refresh` to apply chezmoi changes to the home directory (not `chezmoi apply`) |
38 | | -- It's fine to edit dotfiles directly when testing changes before codifying them in chezmoi |
| 83 | +Code for my personal projects lives in `~/Code`. |
39 | 84 |
|
40 | | -## Dev Tools |
41 | | -{{ if output "sh" "-c" "command -v mise >/dev/null && echo 'yes' || echo 'no'" | trim | eq "yes" -}} |
42 | | -- **Version Manager:** `mise` |
43 | | -- **Runtimes:** |
44 | | -{{ output "sh" "-c" "mise ls --current --no-header 2>/dev/null | awk '{print \" - \" $1 \" \" $2}'" }} |
45 | | -{{ end -}} |
46 | | -- **Docker:** `{{ output "sh" "-c" "command -v docker >/dev/null && echo 'installed' || echo 'not installed'" | trim }}` |
| 85 | +I tend to prefer Go with HTMX, sqlite and `sqlc`, as well as hot-reloading via `air`. |
47 | 86 |
|
48 | | -## Shell Aliases |
| 87 | +The primary reason is just minimal dependency footprint as well as a fast iteration loop. It also allows for integration tests against a real database instead of relying on mocks. |
49 | 88 |
|
50 | | -Prefer these over long-form commands: |
| 89 | +Python is great for scripts though. |
51 | 90 |
|
52 | | -- `refresh` — apply chezmoi changes and reload shell (always use this, NOT `chezmoi apply`) |
53 | | -- `ws` — cd to workspace (`~/Code` or `~/halter` depending on the machine) |
54 | | -- `ss` — cd to `~/Code` |
55 | | -- `venv` — create Python venv and activate it |
56 | | -- `ae` / `de` — activate / deactivate Python venv |
57 | | -- `vi`, `vim`, `lvim` — all aliased to `nvim` |
58 | | -- `ccd` — cd to chezmoi source directory |
59 | | -- `gs` / `gst` — git status |
60 | | -- `gb` — git branch -v |
| 91 | +I'm not opposed to Javascript but it should be ideally treated as progressive enhancement. |
61 | 92 |
|
62 | | -## Editor |
| 93 | +## LLM Runbooks |
63 | 94 |
|
64 | | -- **Neovim** with **LazyVim** (lazy.nvim plugin manager) |
65 | | -- Config at `~/.config/nvim/`, customizations in `lua/plugins/` |
66 | | -- Rely on LazyVim defaults; keep customizations minimal |
| 95 | +I don't really believe in LLMs for user-facing writing as it just becomes slop but when doing tedious infrastructure changes, I sometimes save writeups in `~/Mainframe/Clippings/AI Runbooks/`. |
67 | 96 |
|
68 | | -## Git Workflow |
| 97 | +When working on something generalisable, you should suggest saving a writeup in here. |
69 | 98 |
|
70 | | -- **Signing:** SSH-based, automatic via prepare-commit-msg hook — never skip with `--no-gpg-sign` or `--no-verify` |
71 | | -- **Default branch:** `main` |
72 | | -- **Diff algorithm:** histogram |
73 | | -- **Merge conflict style:** zdiff3 |
74 | | -- **Hooks directory:** `~/.githooks` |
75 | | -- **Zsh framework:** zimfw (NOT oh-my-zsh) |
| 99 | +Don't suggest it for absurdly specific stuff like writing patches and hotfixes. |
76 | 100 |
|
77 | | -## AI Runbooks |
| 101 | +## Common Footguns |
78 | 102 |
|
79 | | -After troubleshooting or debugging sessions that result in useful procedures, suggest saving the solution as a runbook in `~/Mainframe/Clippings/AI Runbooks/`. Don't create automatically — just hint that it might be worth preserving. |
| 103 | +- If I'm running a Go side project, I almost always have a hot reload server in another tab so avoid rebuilding unless asked |
| 104 | +- When working on a side project using sqlite, don't do database mocks. Use a temporary (but real) sqlite instance. |
| 105 | +- Don't add new files when editing an existing one will do the trick. |
0 commit comments