diff --git a/config/claude/CLAUDE.md b/config/claude/CLAUDE.md new file mode 100644 index 0000000..cae28fa --- /dev/null +++ b/config/claude/CLAUDE.md @@ -0,0 +1,32 @@ +# Global Claude Code User Preferences + +Never, under any circumstances, generate code containing new, non-preexisting comments. + +Never, under any circumstances, respond with excerpts of code with no +explanation unless explicitly specified. + +Never, under any circumstances, create commits, stage files, or create pull +requests unless explicitly specified. + +If given express permission to use git, NEVER sign yourself as a contributor OR mention yourself in the PR. + +If given express permission to use git, NEVER push to a main/master branch. + +If given express permission to use git, NEVER commit ai-related files (e.g. CLAUDE.md). + +If given express permission to use git, ALWAYS use this commit message format: + + type(scope): imperative summary + +- Valid types: `feat` `fix` `docs` `refactor` `perf` `test` `ci` `build` `revert` +- Scope is optional, lowercase. Subject: lowercase after colon, no trailing period, max 72 chars. +- Body required for non-trivial commits, using `Problem:` / `Solution:` format. +- One logical change per commit. Refactors, formatting, and features must be separate commits. + +If given express permission to use git, ALWAYS check for a PR template at +`.github/pull_request_template.md` and follow it. If none exists, use +Problem/Solution format as described in `~/.config/claude/rules/git.md`. + +Never, under any circumstances, assume or fabricate APIs for +unknown/lesser-known services and APIs, such as NeoVim, NixOS, or other obscure +packages-always do your research first. diff --git a/config/claude/rules/git.md b/config/claude/rules/git.md new file mode 100644 index 0000000..bebf047 --- /dev/null +++ b/config/claude/rules/git.md @@ -0,0 +1,85 @@ +# Git Workflow Rules + +## Commit Message Format + +``` +type(scope): imperative summary + +Problem: describe the issue or motivation + +Solution: describe what this commit does +``` + +### Header + +- **type** (required): `feat` `fix` `docs` `refactor` `perf` `test` `ci` `build` `revert` +- **scope** (optional): lowercase module/area name, e.g. `feat(parser):` +- **summary**: imperative mood, lowercase after colon, no trailing period, max 72 chars + +### Body + +Required for any non-trivial change. Use `Problem:` / `Solution:` sections. +Wrap at 72 characters. Separate from header with a blank line. + +### Examples + +Good: + +``` +fix(lsp): correct off-by-one in diagnostic range + +Problem: diagnostics highlighted one character past the actual error, +causing confusion when multiple diagnostics appeared on adjacent tokens. + +Solution: subtract 1 from the end column returned by the language server +before converting to 0-indexed nvim columns. +``` + +``` +refactor: extract repeated buffer lookup into helper +``` + +Bad: + +``` +Fixed stuff # not imperative, vague +feat: Add Feature. # uppercase after colon, trailing period +fix(lsp): correct off-by-one in diagnostic range and also refactor the +entire highlight module and add new tests # multiple concerns +``` + +## Branch Naming + +``` +type/short-description +``` + +Examples: `fix/diagnostic-range`, `feat/code-actions`, `refactor/highlight-module` + +## PR Body Format + +If the repo has `.github/pull_request_template.md`, follow that template exactly. + +If no template exists, fall back to: + +``` +## Problem + + + +## Solution + + +``` + +Either way, write in plain prose. No bullet-point walls, no AI-style markdown +headings beyond what the template calls for. Keep it concise and human. + +## Decomposition Rules + +- One logical change per commit. +- Refactors go in their own commit before the feature that depends on them. +- Formatting/style changes are never mixed with behavioral changes. +- Test-only commits are fine when adding coverage for existing code. +- If a PR has more than ~3 commits, consider whether it should be split into + separate PRs. diff --git a/config/claude/skills/commit/SKILL.md b/config/claude/skills/commit/SKILL.md new file mode 100644 index 0000000..fa2a5ed --- /dev/null +++ b/config/claude/skills/commit/SKILL.md @@ -0,0 +1,43 @@ +# /commit + +Create a conventional commit from staged or unstaged changes. + +## Instructions + +1. Run exactly this one Bash command: + ``` + git status --short && echo "---DIFF---" && git diff --cached && echo "---LOG---" && git log --oneline -5 + ``` + +2. If the diff section is empty (nothing staged), ask the user which files to + stage from the status list. Then run exactly one Bash command: + ``` + git add && git diff --cached + ``` + Do NOT re-run status or log — you already have them. + +3. Draft the commit message. Rules: + - Header: `type(scope): imperative summary` — max 72 chars, lowercase after + colon, no trailing period. + - Valid types: `feat` `fix` `docs` `refactor` `perf` `test` `ci` `build` `revert` + - Scope is optional, lowercase. + - Non-trivial changes require a body with `Problem:` / `Solution:` sections, + wrapped at 72 chars, separated from header by a blank line. + - Trivial one-liners: header alone is fine. + - Match the style of the recent commits from step 1. + +4. Present the full message and ask for approval. + +5. After approval, run exactly one Bash command: + ``` + git commit -m "$(cat <<'EOF' + + EOF + )" + ``` + +Total: 2 Bash calls (gather + commit), or 3 if staging was needed. Do not run +any other commands. Do not read files, explore code, or run additional git +commands beyond what is listed above. + +Never amend. Never sign as co-author. Never push. diff --git a/config/claude/skills/pr/SKILL.md b/config/claude/skills/pr/SKILL.md new file mode 100644 index 0000000..44d09bd --- /dev/null +++ b/config/claude/skills/pr/SKILL.md @@ -0,0 +1,44 @@ +# /pr + +Create a pull request from the current branch. + +## Instructions + +1. Run exactly this one Bash command: + ``` + echo "---BRANCH---" && git branch --show-current && echo "---LOG---" && git log --oneline main..HEAD && echo "---STAT---" && git diff main...HEAD --stat && echo "---TEMPLATE---" && cat .github/pull_request_template.md 2>/dev/null || true + ``` + If the branch is `main` or `master`, tell the user and stop. + +2. Draft the PR using the commit log and diffstat (do NOT run `git diff` for the + full diff — you already have conversation context from the work you did): + - **Title**: `type(scope): imperative summary`, max 72 chars. For + single-commit PRs, reuse the commit header. For multi-commit, summarize. + - **Body**: if a PR template was found in step 1, fill it in. Otherwise: + ``` + ## Problem + + + + ## Solution + + + ``` + - Write in plain prose. No bullet walls, no AI markdown soup. + +3. Present the title and body. Ask for approval. + +4. After approval, run exactly one Bash command (push + create chained): + ``` + git push -u origin && gh pr create --title "" --body "$(cat <<'EOF' + <body here> + EOF + )" + ``` + Print the PR URL from the output. + +Total: 2 Bash calls (gather + push/create). Do not run any other commands. Do +not read files, explore code, or run additional git commands beyond what is +listed above. + +Never force-push, even with lease. Never target main/master as the head branch. diff --git a/config/nvim/lua/plugins/git.lua b/config/nvim/lua/plugins/git.lua index ad551c6..33b4f79 100644 --- a/config/nvim/lua/plugins/git.lua +++ b/config/nvim/lua/plugins/git.lua @@ -7,6 +7,7 @@ return { cmd = { 'Git', 'G', 'Gread', 'Gwrite', 'Gdiffsplit', 'Gvdiffsplit' }, }, { + dir = '~/dev/diffs.nvim', 'barrettruth/diffs.nvim', init = function() vim.g.diffs = { diff --git a/home/modules/packages.nix b/home/modules/packages.nix index 40d0774..0c6248e 100644 --- a/home/modules/packages.nix +++ b/home/modules/packages.nix @@ -51,6 +51,18 @@ in }; }; + xdg.configFile."claude/CLAUDE.md" = lib.mkIf enableClaude { + source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/.config/nix/config/claude/CLAUDE.md"; + }; + + xdg.configFile."claude/rules" = lib.mkIf enableClaude { + source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/.config/nix/config/claude/rules"; + }; + + xdg.configFile."claude/skills" = lib.mkIf enableClaude { + source = config.lib.file.mkOutOfStoreSymlink "${config.home.homeDirectory}/.config/nix/config/claude/skills"; + }; + home.activation.linkZenProfile = lib.mkIf enableZen ( lib.hm.dag.entryAfter [ "writeBoundary" ] '' zen_config="$HOME/.zen"