Fix silently broken dotfiles, then modernise conventions - #106
Open
michaelbarton wants to merge 12 commits into
Open
Fix silently broken dotfiles, then modernise conventions#106michaelbarton wants to merge 12 commits into
michaelbarton wants to merge 12 commits into
Conversation
- Stop exporting GIT_AUTHOR_*/GIT_COMMITTER_* from fish, which silently overrode every gitconfig level (including includeIf) and made per-repo identity impossible. git/gitconfig now includes an optional, untracked ~/.config/git/config-local so a work identity can be layered in via hasconfig without naming any employer in this public repo. - Fix ansible/tasks/neovim.yml: TSUpdateSync no longer exists on nvim-treesitter main, so the task was silently exiting 0 without updating parsers. Call the Lua update API synchronously and fail on error. - Drop openssl@1.1 from Brewfile (disabled upstream 2024-09-11). - Remove two atuin config keys that don't exist in current atuin, and enable the daemon (removes an ~50ms subprocess from shell startup). - Wire ansible/requirements.yml into `make galaxy` (now a dependency of `apply`) and both CI workflows — previously installed by nothing. - Remove a dangling ~/.config/git/autocommit.json symlink left over from a removed feature.
Gate the expensive interactive-only setup (starship, tmux auto-attach, zoxide, full mise activation, atuin, fzf keybindings, abbrs) behind `status is-interactive`, so scripts and hooks spawning `fish -c` don't pay for prompt/history/keybinding machinery they never use. The dominant cost was mise: Homebrew's vendor_conf.d/mise-activate.fish runs *before* fish/config.fish and unconditionally pays ~200ms per invocation. Setting MISE_FISH_AUTO_ACTIVATE=0 inside config.fish is too late to help the process that sets it, but is inherited by every fish child process spawned from an already-configured interactive shell (confirmed: nested `fish -c true` drops from 630ms to ~85ms). For the first fish process of a session (no parent to inherit from), the variable has to already be in the environment before fish starts — added via Ghostty's `env` directive, which the profiler confirms drops a fresh `fish -c true` from ~460ms to ~100ms. The non-interactive branch also avoids invoking the `mise` binary at all (even `mise --version` alone costs ~180ms of process startup) — it just prepends the shims dir to PATH directly, per mise's own guidance for scripts. Also: fish_add_path gets --move so it can reorder PATH entries already inherited from a parent environment (previously a no-op if the entry was already present anywhere in PATH) — this is what keeps ~/.local/bin ahead of Homebrew for the `keyring`/keyrings.codeartifact invariant in nested shells. USER_BIN/LOCAL_BIN/HOMEBREW_BIN/HOMEBREW_SBIN/GHOSTTY_BIN/NPM_BIN are now locally scoped scratch vars instead of being exported into every child process.
ruff==0.15.17 was hardcoded in both Makefile and ansible/tasks/neovim.yml (commit #103 already documents drift between these two spots). Add mise.toml pinning ruff, stylua, actionlint, prettier, and ansible-lint; Makefile now calls each via `mise exec --` instead of threading @$(VERSION) through npx/uvx, and ansible/tasks/neovim.yml reads the ruff pin back out with `mise config get tools.ruff` instead of duplicating it. CI installs the pinned versions via jdx/mise-action instead of a bespoke actionlint curl download and an unpinned `uv tool install ansible-lint`. Verified: `make fmt_check` passes end-to-end against the mise-resolved tools, and `mise config get tools.ruff -f mise.toml` / the ansible playbook syntax-check both resolve correctly.
- tmux: replace the pre-3.2 `terminal-overrides ",xterm-ghostty:Tc"` private
extension with `terminal-features RGB` (supported since tmux 3.2, we're on
3.7c). Declare the `extkeys` terminal-feature and extended-keys-format so
tmux actually requests extended keys from Ghostty, per `man tmux`.
- Pin TPM and its plugins instead of floating HEAD: TPM and
vim-tmux-navigator (no useful release tags) pinned to their currently
installed commits; catppuccin/tmux pinned to v2.1.3, which is exactly what
was already installed. Unpinned plugins were the only dependency in this
repo without a lockfile-equivalent, and catppuccin/tmux has a history of
breaking config-API changes between majors.
- Pin GitHub Actions to commit SHAs (with a version comment) instead of
mutable major tags, and add .github/dependabot.yml to keep them current.
- Move tmux.conf, gitconfig, and the global ignore file to their XDG
locations (~/.config/tmux, ~/.config/git/{config,ignore}), dropping
`core.excludesfile` entirely (git's default already points at the XDG
ignore path). Also drops `core.autocrlf` (vestigial on macOS-only),
`branch.autosetupmerge` (already git's default), and
`feature.experimental` (opts into changing behaviour between git
releases). link_files.yml now removes the old ~/.gitconfig/.gitignore/
.tmux.conf symlinks first — git and tmux both prefer the legacy path over
XDG when both exist, so leaving the old links in place would have silently
un-done the migration.
- Trim the global gitignore to what no project ever wants tracked (OS/editor
cruft, secret-shaped filenames) per your call to keep it narrow. A global
excludesfile applies to every repo you touch, so entries like `*.png`,
`Gemfile.lock`, or `*.[1-9]` were silently dropping files in repos that
legitimately track them. Removed patterns are listed in the file's footer
comment for recoverability.
Verified: `make fmt_check`, `tmux -f tmux/tmux.conf` loads cleanly in an
isolated test server, actionlint passes, and an ansible --check --diff dry
run against the new paths confirms the legacy-symlink removal and new XDG
links resolve as intended (no real changes applied — dotfiles_dir still
points at ~/.dotfiles for actual application).
Brewfile: drop pipx (superseded by `uv tool`), iterm2 (Ghostty is the actual terminal in use), the two legacy powerline fonts (superseded by the Nerd Font already installed), the duplicate dockutil cask (keep the brew formula), the standalone npm prettier entry (mise.toml is now the pinned source, used via `mise exec`), and the no-op appdir arg on font casks (fonts don't install to an appdir). Add lefthook so formatting failures are caught before a push instead of a CI run later — a single Go binary, no Python environment to manage. Scoped to `make fmt_check` only; ansible-lint/nvim-check stay CI-only since they're too slow for a commit hook. Installed via a new ansible task (`lefthook install`, tagged lefthook/setup).
personal_hostname: Michaels-MacBook-Air compared against ansible_hostname, but this machine's ansible_hostname is now "michael" (confirmed via `ansible -m setup`) — the machine was renamed at some point and the comparison has silently never matched since, meaning the paperless launch agent has never actually been installed by this task despite looking configured. Replace it with inventory group membership: ansible/inventory.ini's [personal] group now lists the current hostname, and the task checks `ansible_fqdn in groups['personal']`. This scales to a second machine (add a [work] group) without another string literal to keep in sync, and a rename only requires updating the inventory file in one place.
fsmonitor + untrackedCache pairs with the feature.manyFiles already set — per `man git-config`, a background daemon watches the working tree so `git status` skips a full filesystem scan. Also adds fetch.prune/pruneTags, push.followTags, column.ui, diff.mnemonicPrefix, submodule.recurse, and help.autocorrect=prompt — small quality-of-life defaults this repo was missing relative to current git (2.50.1 here, well past the 2.35.1+ fsmonitor requirement).
- theme now follows the system appearance (light:Catppuccin Latte, dark:Catppuccin Frappe), matching the BAT_THEME_DARK/LIGHT pair already set in fish/config.fish and delta's detect-dark-light. Previously pinned to dark, so the terminal was the one thing that didn't switch, and bat/delta would render light themes onto a dark background. - Bind the quick terminal (cmd+`): all quick-terminal-* options were already present but nothing invoked toggle_quick_terminal, in this config or in Ghostty's defaults, so the feature was fully configured and unreachable. - auto-update = off, since Ghostty is installed via the Brewfile cask and its own updater would otherwise silently diverge from what `brew bundle check` reports as installed. - confirm-close-surface = false: tmux persists every session, so the confirmation prompt guards against nothing. Not included: macos-option-as-alt for the tmux M-h/M-l binds (§21c) — needs an interactive Option+h check that can't be verified headlessly, so it's left as a note rather than a blind change. Verified: `ghostty +validate-config` passes.
Global instructions were the one part of the agent tooling here that wasn't version controlled (settings.json, hooks/, and skills/explain already are). Seeds conventions the repo already demonstrates: uv over pip/poetry, just/make task runners, ruff at line-length 100, and running make fmt before committing. Linked into ~/.claude/CLAUDE.md via agent_hooks.yml alongside the existing settings.json/cursor-rules links.
No indentation convention was enforced before formatters ran; editors were relying on their own defaults for YAML, Lua, Python, fish, and shell files in the meantime. Matches the conventions the formatters already enforce: 2-space default, 4-space Python, tabs in Makefile, and no trailing-whitespace trim in Markdown (hard line breaks).
8 of 11 tracked scripts still could not run on system Python 3.9.6: inert metadata (dbt), no metadata (zettel, bioinformatics), a Homebrew python3.10 shebang (dump_schema), or no shebang at all (template_today). Give each the same `# /// script` + `uv run --script` convention the three working scripts already use, drop the leftover poetry symlink from link_files.yml, and run scripts/check_pep723.py from fmt_check so the convention cannot silently rot again. Also restyle hammerspoon/init.lua to 2-space indent so stylua --check agrees with .editorconfig.
Tracked settings.json was a symlink Claude Code writes on every /config change, so the file churned with local state (model) and published work-only marketplace entries. Keep shareable defaults (hooks, permissions, effortLevel, tui, theme) in the repo; model, enabledPlugins, and extraKnownMarketplaces now belong in ~/.claude/settings.local.json, which is already gitignored. Document the split in the README.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the encapsulated-cooking-puffin review: fix the things that were silently dead, then bring the rest of the setup in line with current practice.
GIT_AUTHOR_*/GIT_COMMITTER_*from overriding every gitconfig level, so a work identity can be layered in via an untracked~/.config/git/config-localwithout naming an employer in this public repo.TSUpdateSyncis gone on nvim-treesittermainand was exiting 0), installansible/requirements.ymlfrommake galaxy/apply, dropopenssl@1.1and two dead atuin keys, and remove a dangling git autocommit symlink.MISE_FISH_AUTO_ACTIVATE=0, interactive-only prompt/history,fish_add_path --moveso thekeyringPATH invariant holds in nested shells).mise.toml, Actions to SHAs, and TPM plugins to tags/commits. Move git/tmux to XDG paths, narrow the global gitignore, and finish the PEP 723/uv run --scriptmigration so standalone scripts actually run.model, work marketplace/plugins) out of the tracked publicsettings.json. Lefthook runsmake fmt_checklocally. Ghostty now follows system light/dark and binds the quick terminal.Commit signing (§13) is still skipped on purpose.
macos-option-as-alt(§21c) is left unset pending an interactive Option+h check.Test plan
make fmt_check(already green on this branch)make galaxy && make applyis idempotent on a second run~/.config/git/config-local+config-work, thengit var GIT_AUTHOR_IDENTis the work address in a KariusDx checkout and the personal address in~/.dotfiles./zettel/format_zettel_page.py --help,./bioinformatics/get_multimapping_reads.py --help,./duckdb/dump_schema.py --helpprint usagefish -c trueis under 100ms;fish -l -c 'which git keyring'is Homebrew git and~/.local/bin/keyringtouch a.png && git statusshows?? a.png(global ignore no longer swallows PNGs)macos-option-as-alt = left); system appearance toggles the terminal theme