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>
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 everybombadil link. Edit the source files at the repo root instead. bombadil.tomlis 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 mappingsource(relative to repo) totarget(relative to$HOME).- Templating: files may contain
{{var}}placeholders substituted from the vars files. The active set isvars = ["dark.toml", "vars.toml"]plus whatever profile is selected.vars.tomlholds identity (email,name,signing_key).dark.toml/light.tomlare profile-specific theme variables (alacritty_theme,helix_theme,zellij_theme,bat_theme,theme). Templated files currently includealacritty/alacritty.toml,helix/config.toml,zellij/config.kdl,gitconfig, andbat/config— switchingthemeretints all apps at once via the profile.
Claude Code config (claude/)
~/.claude is partly shared, partly host-specific:
claude/shared/—settings.jsonandstatusline-command.sh, linked on every host (default dots).settings.jsonis the union of both machines' settings; the statusline is one Catppuccin-powerline script merged from both.claude/xps/,claude/desktop/— each host's ownagents/andskills/, linked only by that host's profile.daniel-xpsis the orchestrator that delegates coding subtasks over SSH (desktop-coderagent,desktop-delegateskill);daniel-desktopruns the local Qwen3-Coder model the laptop delegates to (local-coderagent,local-delegate+unload-local-modelskills).
Two bombadil constraints shaped this layout — keep them in mind when adding .claude files:
- 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.mdfile. This also keeps~/.claude/{agents,skills}as real directories, so Claude's own runtime files coexist with the managed ones. - 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.shusesset -- "${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.zshsources every file in~/.config/zsh.d/*(linked fromzsh.d/) then every file in~/.config/aliases.d/*(linked fromaliases.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.zshfile 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.