diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 4efe4e1..0000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,34 +0,0 @@ -# GitHub Copilot Instructions - -## General Instructions - -- This repository contains my dotfiles for various command line tools. The repository is managed by [Chezmoi](https://www.chezmoi.io). -- These dotfiles are primarily used on macOS hosts, but are also intended to work on Debian/Ubuntu hosts. -- These dotfiles primarily support Fish shell (`fish`). -- These dotfiles secondarily support Bash shell (`bash`). -- These dotfiles also support a minimal Z shell (`zsh`) configuration since this is the default shell on macOS. -- When creating YAML files, **always** use the file extension `.yaml` (_never_ `.yml`). - -## Machine Architecture Instructions - -- All my macOS machines are now Apple silicon (also known as _darwin-arm64_ or _macos-arm64_). This repository should assume Apple silicon architecture on macOS. -- On Debian/Ubuntu machines, we cannot assume an architecture. Debian/Ubuntu machines will either be ARM architecture (_amd64_) or Intel architecture (*x86_64*). Where machine architecture may be a factor, there should be a Chezmoi test to determine the machine architecture. - -## Shell Instructions - -- When creating files meant to be executed, read, or sourced by `bash`, use the `.bash` filename extension. -- When creating files meant to be executed, read, or sourced by `fish`, use the `.fish` filename extension. -- When creating files meant to be executed, read, or sourced by `zsh`, use the `.zsh` filename extension. -- When creating general purpose shell scripts, prefer basic Bourne shell (also known as `sh`) without a filename extension. Make the script executable (for example: `chmod 755 example-script-name`). Use the file header `#!/usr/bin/env sh` to ensure finding the correct `sh` executable. -## Tools Instructions - -- [`1Password`](https://1password.com) is used to store secrets that should not be stored in version control. The [`op`](https://developer.1password.com/docs/cli/) should be installed on each machine. Chezmoi has built-in support for retrieving secrets from 1Password. -- `apt` is preferred to `apt-get` when installing software on Debian/Ubuntu hosts. -- [`goenv`](https://github.com/go-nv/goenv) is used for Golang version management. -- [Hammerspoon](https://www.hammerspoon.org) for additional window management and general UI scripting on macOS machines. -- [Homebrew](https://brew.sh) is use for installing command line tools and graphical user interface applications (using the `--cask` option) on macOS. -- [`nodenv`](https://github.com/nodenv/nodenv) is used for NodeJS version management. -- [`rbenv`](https://github.com/rbenv/rbenv) is used for Ruby version management. -- [Starship](https://starship.rs) is the prompt tool used for Fish shell and Bash shell. -- [`tenv`](https://tofuutils.github.io/tenv/) is used for managing Terraform versions. -- [`uv`](https://docs.astral.sh/uv/) is used for Python version management, Python virtual environment management, and Python dependency management. diff --git a/.rumdl.toml b/.rumdl.toml index b1a91b6..7378cdc 100644 --- a/.rumdl.toml +++ b/.rumdl.toml @@ -43,6 +43,10 @@ exclude = [ # Respect .gitignore files when scanning directories (default: true) respect_gitignore = true +# Per-file rule ignores +[per-file-ignores] +"CLAUDE.md" = ["MD041"] + # Markdown flavor/dialect (uncomment to enable) # Options: standard (default), gfm, commonmark, mkdocs, mdx, quarto # flavor = "mkdocs" diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c4de1b9 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,22 @@ +# Dotfiles (chezmoi) + +This repo manages personal dotfiles via [chezmoi](https://www.chezmoi.io). + +## Chezmoi filename conventions + +- `dot_` prefix → `.` in the home directory (e.g. `dot_bashrc` → `~/.bashrc`) +- `private_` prefix → file is created with mode 0600 +- `.tmpl` suffix → Go template; rendered with chezmoi data before applying +- `executable_` prefix → file is made executable + +## Working with templates + +Templates use `{{ .chezmoi.* }}` variables (e.g. `{{ .chezmoi.os }}`, `{{ .chezmoi.hostname }}`). Data is defined in `~/.config/chezmoi/chezmoi.toml` on each machine — do not commit secrets there. + +## Testing changes + +```sh +chezmoi diff # preview what would change on the local machine +chezmoi apply # apply changes +chezmoi doctor # check for configuration issues +``` diff --git a/CLAUDE.md b/CLAUDE.md index ff6d712..43c994c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,72 +1 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Repository purpose - -Personal dotfiles managed by [chezmoi](https://www.chezmoi.io). Primary target is macOS (Apple silicon); secondary target is Debian/Ubuntu (arch must be detected, never assumed). Windows is partially supported via `.chezmoiignore` exclusions. - -Shell support, in priority order: **fish** (primary), **bash** (secondary), **zsh** (minimal — it's just macOS's default login shell). - -## Working with chezmoi source files - -This repo **is** the chezmoi source directory (`$(chezmoi source-path)` points here). Files here are not the files that land in `$HOME` — chezmoi renames them on `apply` using prefix conventions. When creating or renaming files, pick the right prefix or the file will land in the wrong place with the wrong permissions: - -- `dot_` → `.` (e.g. `private_dot_bashrc` → `~/.bashrc`) -- `private_` → mode `0600` / `0700` (owner-only) -- `executable_` → mode `0755` -- `.tmpl` suffix → processed as a Go text/template with chezmoi's template functions (`.chezmoi.os`, `.chezmoi.hostname`, `onepasswordRead`, etc.) - -When adding a script to `private_dot_local/private_bin/`, the filename must start with `private_executable_` for it to be installed as an executable in `~/.local/bin/`. - -### Common commands - -```sh -chezmoi diff # preview what `apply` would change in $HOME -chezmoi apply -v # apply changes from this repo to $HOME -chezmoi apply # apply a single target (path in $HOME) -chezmoi execute-template < file.tmpl # render a template to stdout for debugging -chezmoi edit # edit the source file that maps to a $HOME path -chezmoi cd # open a shell in the source directory (here) -``` - -After editing files **in this repo directly**, run `chezmoi diff` before `chezmoi apply` to confirm the rename/template resolution produces what you expect. - -## Platform/host gating - -Two layers of conditional logic, used together: - -1. **`.chezmoiignore`** — Go templates decide which source files are *skipped entirely* per machine. Current rules gate macOS-only files (`hammerspoon`, several `bin/` scripts), work-machine-only files (ALKS config, `.netrc`, `.npmrcs`) behind a hostname check against a 1Password-stored hostname, and Linux-only files. -2. **`.tmpl` files** — Template conditionals (`{{ if eq .chezmoi.os "darwin" }}…{{ end }}`) branch *within* a file. Used heavily in fish `conf.d` and bashrc.d `tools/` for language-version-manager PATH setup (goenv/nodenv/rbenv/tenv/uv). - -When adding a macOS-only binary, Linux-only config, or work-only secret, update `.chezmoiignore` rather than sprinkling conditionals inside a template — keep per-file skips in the ignore file, and per-section branching in `.tmpl`. - -## Shell config layout - -Both shells load config fragments from a directory so features can be added per-file without touching the main rc file: - -- **bash**: [private_dot_bashrc](private_dot_bashrc) sources `~/.bashrc.d/**/*.bash` (globstar). Fragments live in [private_dot_bashrc.d/](private_dot_bashrc.d/) under `aliases/`, `configuration/`, `functions/`, `tools/`. -- **fish**: [private_dot_config/private_fish/](private_dot_config/private_fish/) uses fish's native `conf.d/` with a numeric prefix ordering convention — `00-path-*` (PATH setup first), `10-*` (aliases/abbreviations), `20-*`/`80-*` (tool config), `90-*` (env vars last). Preserve that ordering when adding fragments. Named functions live in `private_functions/` (→ `~/.config/fish/functions/`). - -Both shells initialize **starship** and **direnv**, and rely on **Homebrew** (`/opt/homebrew/bin/brew` on Apple silicon, `/usr/local/bin/brew` on Intel fallback). - -## Secrets - -Secrets come from **1Password** via `onepasswordRead "op://Vault/item/field"` in templates — `op` CLI must be installed and signed in on every machine. Never hardcode secrets; never commit them. The work-machine gate (see `.chezmoiignore` line 19) reads a stored hostname from 1Password and uses it to decide whether to deploy work-only files. - -## Linting - -Markdown files are linted with [`rumdl`](https://github.com/ericmjl/rumdl). Config lives in [.rumdl.toml](.rumdl.toml) (MD013 line-length disabled). Run: - -```sh -rumdl . -``` - -## File conventions - -From [.github/copilot-instructions.md](.github/copilot-instructions.md), also applicable here: - -- Shell file extensions are load-bearing: `.bash`, `.fish`, `.zsh` for files sourced/executed by that specific shell. For portable scripts, prefer POSIX `sh` with no extension, `#!/usr/bin/env sh` shebang, and `chmod 755`. -- Always use `.yaml`, never `.yml`. -- Prefer `apt` over `apt-get` on Debian/Ubuntu. -- Language version managers in use: `goenv`, `nodenv`, `rbenv`, `tenv` (Terraform), `uv` (Python). Don't introduce alternatives (pyenv, nvm, asdf) without a reason. +@AGENTS.md