chezmoi dotfiles の運用
このスキルは、このリポジトリの dotfiles を変更するときに使う。 常に chezmoi の source state を正とし、ターゲットファイルを直接編集しない。
リポジトリ構造
.chezmoirootが source state のルートとしてchezmoi/を指定する。chezmoi/配下のdot_、private_dot_、executable_、symlink_などは chezmoi の source state attributes である。 属性を変えるときは命名規則を手で推測せず、chezmoi chattrと公式リファレンスを確認する。chezmoi/dot_claude/は~/.claude/、chezmoi/dot_zshrc.tmplは~/.zshrc、chezmoi/private_dot_config/は~/.config/に対応する。shell/は working tree に置く共有シェルスクリプトである。.zshrcはshell/sharedrc.shを読み込み、sharedrc.shはshell/alias.shを読み込む。shell/localrc.shは Git 管理しないマシン固有の上書き用である。config/は chezmoi のターゲットではない配布用設定、scripts/はセットアップ・保守スクリプト、internal/は設定を配布する TypeScript CLI である。
このリポジトリでの編集規約
~/.zshrc、~/.config/**、~/.claude/**など、chezmoi 管理下のターゲットは編集しない。 対応するchezmoi/のソースを編集する。- このリポジトリを checkout して作業するときは、
chezmoi/を直接編集してよい。 稼働中のターゲットから取り込む必要があるときはchezmoi add、chezmoi re-add、またはchezmoi mergeを用途に応じて使う。re-addはテンプレートと併用できない。 - 対話的に source state を編集するだけなら
chezmoi edit <target>も使える。 テンプレート・暗号化ファイルを透過的に扱えるが、このリポジトリの変更として残すには Git diff を必ず確認する。 - 新しい依存関係は、まず
nix search nixpkgs <package>で nixpkgs を確認する。 見つかったlegacyPackages.<system>.<name>は通常pkgs.<name>としてchezmoi/private_dot_config/home-manager/home.nix.tmplに追加する。 npm のグローバルインストールや手動ダウンロードより home-manager を優先する。 - Node.js などのランタイムバージョンは
chezmoi/private_dot_config/mise/config.tomlで管理する。
Skill / Agent 設定を chezmoi で配布するときの注意
chezmoi/dot_agents/skills/、chezmoi/dot_claude/、chezmoi/dot_codex/ 配下は chezmoi の source state である。
source state のルールがそのまま効くため、普通のディレクトリのつもりでファイルを置くと配布されない。
- ドット始まりのファイル・ディレクトリは配布されない。
chezmoi は source state 内の
.始まりエントリを chezmoi 自身の特殊ファイル (.chezmoiignoreなど) として扱い、 それ以外は無視する。references/core/.envrcのようにコミットしても~/.agents/.../core/.envrcは生成されない。 Git 上には存在するのでlsでは気付けない。- dotfile を配布したい場合は
dot_属性を使う (dot_envrc→.envrc)。 - skill の reference テンプレートは、そのまま使う dotfile ではなくコピー元なので、
ドットなしの名前 (
envrc、oxfmtrc.json、agents/) にして、コピー先を index.md に明記する方を優先する。 配布後も可視ファイルとして残り、skill を使うエージェントが発見できる。
- dotfile を配布したい場合は
READMEのような普通の名前でも、.chezmoiignoreの対象に入っていないか確認する。- 属性付きの名前 (
private_、executable_、symlink_、literal_など) は意図せず解釈されることがある。 ファイル名そのものを残したいときはliteral_を使う。
chezmoi verify は「chezmoi が管理していると認識しているターゲット」しか見ないため、
無視されて配布されなかったファイルは検出できない。
ファイルを追加・リネームしたら、次の 2 つで確認する。
# 1. source state 内に配布されないドット始まりエントリがないか
find chezmoi -name '.*' -not -name '.chezmoi*'
# 2. 追加したファイルが管理対象に入っているか (出力があれば配布される)
chezmoi managed | grep '<配布先の相対パス>'
1 が何かを出力したら、意図的な chezmoi 特殊ファイルでない限りバグである。
テンプレート
- 環境差分が必要な部分だけ
.tmplを使う。 chezmoi のテンプレートは Gotext/templateと Sprig 関数に基づく。 - OS・配布版の条件分岐には
.chezmoi.os、.chezmoi.osReleaseなどの chezmoi data を使う。 既存例はchezmoi/dot_zshrc.tmplを参照する。 - 変更が複数ファイルで共有されるなら
.chezmoitemplates/に断片を置くことを検討する。 データ値は.chezmoidata.{toml,yaml,json,jsonc}または chezmoi 設定のdataに集約し、テンプレートへ値を散在させない。 - テンプレートを変更したら、必要に応じて
chezmoi execute-templateで評価する。{{-と-}}で意図しない空白・改行を除去できる。
秘密情報
- 秘密情報、トークン、秘密鍵、マシン固有値を平文でコミットしない。
このリポジトリでは 1Password 参照を含む
shell/env-secrets.sh.tplがあり、生成物は Git 管理外に置く。 - chezmoi に暗号化して保存する必要がある場合は
chezmoi add --encryptを使う。 新規の暗号化バックエンドには age を優先し、復号・鍵管理・ローテーション方法を先に確認する。 - 秘密情報を含む変更は、適用前に
git diff --checkとgit diffを必ず確認する。
変更・適用・検証の手順
- source state を変更する。
chezmoi diffで target state と現在のターゲットとの差分を確認する。 影響範囲を先に確認するだけならchezmoi apply --dry-run --verboseを使う。chezmoi applyで反映する。 このリポジトリでは zeno のdotfiles-applyabbreviation が、chezmoi apply --no-tty --keep-going、環境変数の読み込み、home-manager switch、internal-cli pi-agent deliver、internal-cli merge-configを連結する。 これは zsh/zeno の abbreviation であり、非対話シェルや CI でコマンドとして存在するとは限らない。 必要な処理は個別コマンドとして明示して実行する。- 反映後は
chezmoi verifyで target state との一致を確認する。chezmoi verifyは成功時に終了コード 0 を返すため、自動検証にも使える。 - Nix の変更は
home-manager switchの成否も確認する。 シェル設定を変更した場合は、新しいログインシェルまたはsourceで読み込んだ後の動作も確認する。
reload は chezmoi apply && home-manager switch && source ${CHEZMOI_WORKING_TREE}/shell/sharedrc.sh、reload-force は最後に exec $SHELL -l を実行する zeno abbreviation である。
初期セットアップと CI
新しいマシンでは以下のセットアップスクリプトを使う。
bash -c "$(curl -fsLS https://raw.githubusercontent.com/d-kimuson/dotfiles/refs/heads/main/scripts/setup.sh)"CI は Ubuntu 上で
chezmoi init --apply -S .を実行する。 Linux で成立しない macOS 固有の変更、秘密情報への依存、対話入力を必要とする変更を追加しない。