Nix Flakes + home-manager で宣言的に管理しており、Claude Code・git worktree・Agent Skills が中心的な役割を担っている。
Claude Code の設定
Nix による宣言的管理
nix/modules/home/programs/claude-code.nix で ~/.config/claude/settings.json を生成している。
xdg.configFile."claude/settings.json".text = builtins.toJSON {
env = {
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1";
};
enabledPlugins = {
"gopls-lsp@claude-plugins-official" = true;
};
language = "Japanese";
statusline = {
type = "command";
command = "ccusage statusline";
};
hooks = {
WorktreeCreate = [{ hooks = [{ type = "command"; command = "…/hooks/worktree.zsh"; }]; }];
WorktreeRemove = [{ hooks = [{ type = "command"; command = "…/hooks/worktree.zsh"; }]; }];
};
};ポイント:
- Agent Teams を実験的に有効化
- statusline に
ccusageを使いトークン使用量を表示 - Worktree フック で後述の git worktree と連携
- ビルド時に JSON Schema によるバリデーションを実行
Symlink 戦略
claude/ ディレクトリ以下のファイルは mkOutOfStoreSymlink で Nix Store を経由せず直接シンボリックリンクされる。これにより nix run .#switch なしでも即座に反映される。
claude/hooks/ → ~/.config/claude/hooks
claude/CLAUDE.md → ~/.config/claude/CLAUDE.md
claude/commands/ → ~/.config/claude/commands
claude/agents/ → ~/.config/claude/agents
claude/rules/ → ~/.config/claude/rules
claude/output-styles/ → ~/.config/claude/output-styles
プロジェクトフック (.claude/settings.json)
dotnix リポジトリ自体にもプロジェクトレベルのフックが設定されている。
| イベント | マッチャー | アクション |
|---|---|---|
| PostToolUse | Edit|Write|NotebookEdit | nix run .#fmt (自動フォーマット) |
| PostToolUse | Task | entire hooks claude-code post-task |
| PostToolUse | TodoWrite | entire hooks claude-code post-todo |
| PreToolUse | Task | entire hooks claude-code pre-task |
| SessionStart | - | entire hooks claude-code session-start |
| SessionEnd | - | entire hooks claude-code session-end |
| Stop | - | entire hooks claude-code stop |
| UserPromptSubmit | - | entire hooks claude-code user-prompt-submit |
ファイル編集後に自動で treefmt が走るため、フォーマットの手動実行が不要。Entireでプロンプトをチームに共有している。
ルール
claude/rules/ に配置したルールファイルは全プロジェクトに適用される。
- plan-review.md — プラン提示前に
codex exec -m gpt-5.3-codexでレビューし、クリティカルな問題がなくなるまで反復する - cargo-registry.md — Rust プロジェクトで
~/.cargo/registry/src/の読み取りを許可
グローバル CLAUDE.md
Always prefer simplicity over pathological correctness.
YAGNI, KISS, DRY.
No backward-compat shims or fallback paths unless they come free
without adding cyclomatic complexity.
全プロジェクトにおけるエージェントの行動指針。過剰な設計を防ぎ、シンプルさを最優先にする。
Git Worktree ワークフロー
基本設定
git.nix で worktree のベースディレクトリを設定:
settings = {
wt.basedir = ".git/wt";
push.autoSetupRemote = true;
init.defaultBranch = "main";
};git wt コマンド (git-wt パッケージ) により、.git/wt ディレクトリ配下に worktree が作成される。メインの作業ツリーを汚さずに並行作業ができる。
.gitの中であれば、リンターなどが干渉する心配もない。
Claude Code との連携
Claude Code が worktree を作成/削除するとき、自動的にフックが発火する:
# claude/hooks/worktree.zsh
input=$(cat)
hook_event=$(printf '%s' "$input" | jq -r '.hook_event_name')
case "$hook_event" in
WorktreeCreate)
wt_name=$(printf '%s' "$input" | jq -r '.name')
wt_abs_path=$(git wt "$wt_name" --nocd 2>/dev/null | tail -n 1 | xargs)
echo "$wt_abs_path"
;;
WorktreeRemove)
wt_path=$(printf '%s' "$input" | jq -r '.worktree_path')
git wt -d "$wt_path" 2>/dev/null || true
;;
esacClaude Code の Agent Teams 機能で並列にタスクを進める際、各エージェントが独立した worktree で作業できる。
シェル関数
日常的な worktree 操作用のシェル関数も用意されている。
gwt — fzf で worktree を選択して移動:
function gwt() {
local worktree=$(git wt | fzf --header-lines=1 | awk '{if ($1 == "*") print $2; else print $1}')
[[ -n "$worktree" ]] && cd "$worktree"
}git-wt-clean — リモートでマージ済み (gone) の worktree とブランチを一括削除:
function git-wt-clean() {
git fetch --prune
local branches=$(git branch -vv | grep ': gone]' | sed 's/^[* +]*//' | awk '{print $1}')
# 対話的に確認してから削除
echo "$branches" | while read -r branch; do
git wt -d "$branch" 2>/dev/null || git branch -d "$branch" 2>/dev/null || true
done
}.envrc によるポート干渉の回避
git worktree を多用すると避けられないのがポート干渉の問題。メインツリーと worktree で同時に pnpm dev すると、同じポート番号を取り合って EADDRINUSE エラーになる。
.envrc + direnv でこれを解決している。worktree 名からハッシュを計算し、ポート番号を動的に割り当てる仕組み:
# .envrc
use flake
# worktree 内の場合、ポート番号を動的に割り当て
if [[ $(pwd) =~ \.wt/([^/]+) ]]; then
WORKTREE_NAME="${BASH_REMATCH[1]}"
HASH=$(echo -n "$WORKTREE_NAME" | cksum | cut -d' ' -f1)
export PORT=$((3000 + HASH % 100)) # Next.js
export SERVER_PORT=$((8080 + HASH % 100)) # Hono
echo "Worktree: $WORKTREE_NAME (PORT: $PORT, SERVER_PORT: $SERVER_PORT)"
else
export PORT=3000
export SERVER_PORT=8080
fiポイント:
- 決定論的: 同じ worktree 名なら常に同じポートが割り当てられる (
cksumによるハッシュ) - 衝突回避: メインは 3000/8080 固定、worktree は 3001-3099/8081-8179 の範囲
- 透過的:
PORTやSERVER_PORT環境変数を参照するフレームワーク (Next.js, Hono 等) はコード変更不要 - direnv 統合: ディレクトリに
cdするだけで自動適用。direnv allow後は意識する必要がない
docker-compose でも同様に ${DATABASE_PORT:-5432} で受ければ、DB ポートも worktree ごとに分離できる。
worktree 作成時のフックと組み合わせると、セットアップも自動化できる:
git config --add wt.hook 'direnv allow && eval "$(direnv export bash 2>/dev/null)" && pnpm install'Portless — 今後試したいアプローチ
ポートのハッシュ割り当ては実用的だが、「ポート番号を人間が覚える」問題は残る。Portless はこの問題を根本から解決するツール。
# 従来
http://localhost:3000 → Next.js
http://localhost:8080 → API サーバー
# Portless
http://foo.localhost:1355 → Next.js
http://api.bar.localhost:1355 → API サーバー
仕組み:
- ポート 1355 でプロキシが起動
- アプリ起動時にランダムポート (4000-4999) を割り当て、名前とマッピングを登録
<name>.localhost:1355へのリクエストを適切なバックエンドにルーティング
worktree との相性がよく、feature-x.localhost:1355 のように worktree ごとに名前付き URL を持てるため、ポート番号を一切意識しなくてよくなる。HTTP/2 + HTTPS もサポートしており、Cookie の分離も自動で行われる。
典型的なフロー
1. gwt → fzf で既存 worktree に移動
2. git wt feature-x → 新しい worktree を .wt/feature-x に作成
3. (direnv が自動でポート割り当て)
4. pnpm dev → 干渉なしで開発サーバー起動
5. git-wt-clean → マージ済み worktree を一掃
Claude Code 経由の場合は Agent Teams が自動で worktree を作成・管理してくれる。
Agent Skills エコシステム
agent-skills-nix による管理
agent-skills-nix を使い、スキルのソース管理とデプロイを宣言的に行う。
programs.agent-skills = {
enable = true;
sources = {
local = { path = local-skills; subdir = "agents/skills"; };
anthropic = { path = anthropic-skills; subdir = "skills"; };
vercel = { path = vercel-skills; subdir = "skills"; };
# ...
};
skills.enableAll = [ "local" ]; # ローカルスキルは全有効化
skills.explicit = { … }; # 外部スキルは個別指定
targets = {
agents = { dest = ".agents/skills"; structure = "link"; };
claude = { dest = ".config/claude/skills"; structure = "link"; };
codex = { dest = ".config/codex/skills"; structure = "link"; };
};
};nix run .#switch するだけで Claude Code と Codex の両方にスキルがデプロイされる。
ローカルスキル一覧
| スキル | 言語 | 用途 |
|---|---|---|
| social-digest | TypeScript (Bun) | Discord + Mastodon の日次投稿を Obsidian に保存 |
| oura-daily-watch | Python | Oura Ring データ + Discord 行動分析 |
| check-similarity | TypeScript | AST ベースの重複コード検知 |
| dce | TypeScript | ts-remove-unused によるデッドコード検出・除去 |
| gha-lint | YAML | GitHub Actions のセキュリティ & リント (actionlint, pinact, ghalint, zizmor) |
social-digest
Discord Bot Token と Mastodon Token を使い、前日の投稿を取得。URL のトラッキングパラメータ除去、X/Twitter の FixTweet API 対応など、データクレンジングも含む。出力は YAML frontmatter 付きの Markdown で、Obsidian に直接保存される。
oura-daily-watch
Oura Ring API v2 から睡眠・準備・活動スコアを取得し、7日間のベースラインと比較。異常検知フラグ (READINESS_DROP, SHORT_SLEEP, RHR_SPIKE 等) を付与する。
gha-lint
4つのツールを組み合わせた GitHub Actions セキュリティ分析:
- actionlint — 構文・型チェック
- pinact — アクション参照の SHA ピン留め (サプライチェーン攻撃対策)
- ghalint — セキュリティベストプラクティス
- zizmor — 脆弱性分析 (regular/pedantic/auditor の3段階)
外部スキル
| スキル | ソース | 用途 |
|---|---|---|
| docx, pdf, pptx, xlsx | Anthropic 公式 | ドキュメント処理 |
| frontend-design | Anthropic 公式 | フロントエンドデザイン支援 |
| find-skills | Vercel Labs | スキル検索・発見 |
| ui-ux-pro-max | コミュニティ | UI/UX デザインシステム生成 |
| ast-grep | ast-grep | AST ベースのコード検索・変換 |
シェルワークフロー
dev — tmux セッション管理
VSCode 風のマルチプロジェクト開発環境を tmux で実現:
┌──────┬────────────────┐
│ │ │
│keifu │ nvim │
│ │ │
│ ├────────────────┤
│ │ shell │
└──────┴────────────────┘
dev # 全プロジェクトを開く
dev <name> # 特定プロジェクトを開く
dev add [name] # プロジェクト作成 (カレントディレクトリ)
dev config [name] # シェルコマンド設定
dev restart [name] # シェルペイン再起動
dev stop # セッション終了
dev ls # 一覧表示各プロジェクトの設定は ~/.config/dev-tmux/<name>.conf に保存される。
Claude Code中心のMac開発環境を整備する - tmux・Ghostty・Discord通知 - 逆瀬川ちゃんのブログ
Jujutsu (jj)
Git と並行して Jujutsu も使える設定になっている:
jj pull # → jj git fetch && jj rebase -d main
jj st # → jj status
jj l # → jj log -n 10
jj fresh # → jj new mainjb — fzf でブックマークを選択して jj new:
jb # → jj bookmark list | fzf → jj new <bookmark>Z.AI — Agent Team のコスト削減
Agent Teams は便利だが、Teammate (子エージェント) のトークン消費が大きい。この記事で紹介されている手法を参考に、Teammate のモデルを Z.AI (GLM Coding Plan) 経由の GLM-5 に差し替えてコストを削減している。
# claude-zai: Z.AI API 経由で Claude Code を実行
function claude-zai() {
env \
ANTHROPIC_BASE_URL="https://api.z.ai/api/anthropic" \
ANTHROPIC_AUTH_TOKEN="${ANTHROPIC_AUTH_TOKEN:-xxxx}" \
API_TIMEOUT_MS="3000000" \
ANTHROPIC_DEFAULT_OPUS_MODEL="GLM-5" \
ANTHROPIC_DEFAULT_SONNET_MODEL="GLM-5" \
ANTHROPIC_DEFAULT_HAIKU_MODEL="GLM-4.7" \
claude -w "$@"
}構成:
- Lead (親): Claude Opus をそのまま使用 — 全体の設計・指示出し
- Teammate (子): GLM-5 に切り替え — 実装・作業の実行
ct 関数で Teammate モードを起動する:
# ct: Claude Code teammate mode (tmux)
function ct() {
CLAUDE_CODE_TEAMMATE_COMMAND="claude -w $*" \
claude --dangerously-skip-permissions --teammate-mode tmux "$@"
}CLAUDE_CODE_TEAMMATE_COMMAND に claude-zai を指定すれば、Lead は Opus のまま、Teammate だけ GLM-5 で動く。司令塔の判断品質を維持しつつ、作業者のコストを抑えるアプローチ。
Codex CLI との連携
Claude Code だけでなく、OpenAI の Codex CLI も設定されている。
# ~/.config/codex/config.toml
model = "gpt-5.3-codex"
approval_policy = "on-request"
model_reasoning_effort = "high"
project_doc_fallback_filenames = ["CLAUDE.md"]CLAUDE.md をプロジェクトドキュメントとして共有し、Claude Code と Codex で統一された指示を参照できる。
クロスツールレビュー
claude/rules/plan-review.md で、Claude Code が生成したプランを Codex にレビューさせるワークフローが定義されている:
# Claude Code がプランを生成 → Codex でレビュー
codex exec -m gpt-5.3-codex \
"Review this plan. No nitpicks. Only flag critical issues: {plan_path}"
# 修正後に再レビュー (前回のコンテキストを引き継ぐ)
codex exec resume --last -m gpt-5.3-codex \
"Plan updated. Review again. No nitpicks. Only flag critical issues: {plan_path}"「nitpick 不要、クリティカルな問題のみ指摘」という指示で、実用的なフィードバックに絞っている。異なる LLM にレビューさせることで、単一モデルの盲点を補完する効果がある。
MCP サーバー
DeepWiki MCP サーバーが設定されており、GitHub リポジトリのドキュメントを AI 経由で検索・質問できる:
{
"mcpServers": {
"deepwiki": {
"type": "http",
"url": "https://mcp.deepwiki.com/mcp"
}
}
}まとめ
このワークフローの特徴:
- 宣言的管理 — Nix Flakes ですべてを再現可能に。
nix run .#switch一発で環境を同期 - Worktree 中心の並行作業 —
.wt/ベースの worktree + Claude Code フックで、Agent Teams が自動的に独立した作業空間を確保。direnv によるポート動的割り当てで干渉を回避 - スキルの統一配信 — agent-skills-nix で Claude Code / Codex に同じスキルセットをデプロイ
- 自動化されたフック — ファイル編集時の自動フォーマット、セッションのライフサイクル追跡、worktree の自動管理
- クロスツール連携 — Claude Code のプランを Codex でレビュー、Z.AI による API プロバイダ切り替えなど、複数 AI ツールを相互補完的に活用
- 今後の展望 — Portless による名前付き URL での worktree 開発環境の完全なポートレス化