Files
dotfiles/CLAUDE.md
T
daniel e884e4a88f Manage Claude Code config + add Justfile via bombadil
Bring ~/.claude config under bombadil management across both machines:
- claude/shared/: converged settings.json (union of both hosts) and a single
  Catppuccin-powerline statusline merged from the two machines' versions
- claude/xps, claude/desktop: per-host agents/skills behind [profiles.xps]/
  [profiles.desktop]; each host links only its own via `bombadil link -p <theme> <host>`

Linked at file granularity because bombadil 4.2.0 can't create directory
symlinks for new targets, and to keep ~/.claude/{agents,skills} real dirs.

Add a Justfile (symlinked to ~/.justfile, usable via `just -g`) with link/
dark/light/watch/unlink/update/status/edit recipes; host auto-detected from
hostname. Recipes use exported shell vars to avoid bombadil's Tera engine
mis-parsing just's double-brace interpolation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 17:17:17 -05:00

5.0 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

Personal dotfiles managed by Bombadil. Source config files live at the top level of this repo. Bombadil renders them (substituting template variables) into .dots/, then symlinks the rendered files into $HOME / ~/.config according to bombadil.toml.

Applying changes

This repo is checked out on two machines sharing one bombadil.toml: daniel-xps (laptop) and daniel-desktop (GPU box). Each links with both a theme profile and its host profile. Easiest is the Justfile (symlinked to ~/.justfile, auto-detects the host):

just -g link     # render -> .dots/ and relink for this host + the dark theme
just -g light    # relink with the light theme
just -g update   # git pull --ff-only, then relink
just -g          # list all recipes

Equivalent raw commands:

bombadil link -f -p dark xps       # on daniel-xps
bombadil link -f -p dark desktop   # on daniel-desktop

Edits do not take effect until linked. Always include the host profile (xps/desktop) — a plain bombadil link won't link that host's Claude agents/skills. -f is needed when a target already exists as a real file; bombadil backs it up to *.bak (clean those up afterward). The repo is registered globally via ~/.config/bombadil.toml (a symlink to bombadil.toml here, created once by bombadil install).

Key conventions

  • Never edit .dots/. It is Bombadil's generated output (not tracked by git) and is overwritten on every bombadil link. Edit the source files at the repo root instead.
  • bombadil.toml is the source of truth for what gets linked where. Adding a new config means: add the file at the repo root, then add a [settings.dots] entry mapping source (relative to repo) to target (relative to $HOME).
  • Templating: files may contain {{var}} placeholders substituted from the vars files. The active set is vars = ["dark.toml", "vars.toml"] plus whatever profile is selected. vars.toml holds identity (email, name, signing_key). dark.toml / light.toml are profile-specific theme variables (alacritty_theme, helix_theme, zellij_theme, bat_theme, theme). Templated files currently include alacritty/alacritty.toml, helix/config.toml, zellij/config.kdl, gitconfig, and bat/config — switching theme retints all apps at once via the profile.

Claude Code config (claude/)

~/.claude is partly shared, partly host-specific:

  • claude/shared/settings.json and statusline-command.sh, linked on every host (default dots). settings.json is the union of both machines' settings; the statusline is one Catppuccin-powerline script merged from both.
  • claude/xps/, claude/desktop/ — each host's own agents/ and skills/, linked only by that host's profile. daniel-xps is the orchestrator that delegates coding subtasks over SSH (desktop-coder agent, desktop-delegate skill); daniel-desktop runs the local Qwen3-Coder model the laptop delegates to (local-coder agent, local-delegate + unload-local-model skills).

Two bombadil constraints shaped this layout — keep them in mind when adding .claude files:

  1. File-level dots only. bombadil 4.2.0 cannot create a directory symlink for a not-yet-linked target (fails with IoError: the source path is neither a regular file nor a symlink to a regular file). So every agent/skill file is its own dot entry mapping a single .md file. This also keeps ~/.claude/{agents,skills} as real directories, so Claude's own runtime files coexist with the managed ones.
  2. Tera escaping. Sources render through Tera, which treats {{, {%, and {# as template syntax. The shell array-length form ${#arr[@]} contains {# and breaks rendering — avoid it in any linked script (claude/shared/statusline-command.sh uses set -- "${arr[@]}"; n=$# instead). Watch out for the same sequences in comments.

zsh layout

  • zshenv.zsh~/.zshenv (env vars, editor detection), zshrc.zsh~/.zshrc (interactive setup).
  • zshrc.zsh sources every file in ~/.config/zsh.d/* (linked from zsh.d/) then every file in ~/.config/aliases.d/* (linked from aliases.d/). Each file is a self-contained conf.d-style snippet for one tool (e.g. zsh.d/git.zsh, aliases.d/cargo.zsh). Add a tool by dropping a new .zsh file in the matching directory — no central registration needed.
  • Machine-specific overrides are sourced if present and are intentionally not in this repo: ~/.zshenv.local, ~/.zshrc.local, ~/.aliases.local.
  • Tool integrations guard on availability with if (( $+commands[tool] )); then ... — follow this pattern so configs degrade gracefully on machines lacking a tool. The prompt (zsh.d/prompt.zsh) falls back starship → p10k → manjaro.

Submodules

alacritty/themes (and a legacy alacritty-theme) are git submodules pointing at the upstream alacritty color-theme collection. Run git submodule update --init after cloning.