ankuro.dev
← ブログ一覧に戻る
【Claude Code中級編 #8】CwdChangedとFileChanged——ディレクトリ移動・ファイル変更に反応するHooks
2026-03-26#Claude Code#AI#Hooks#環境管理#direnv

【Claude Code中級編 #8】CwdChangedとFileChanged——ディレクトリ移動・ファイル変更に反応するHooks

Claude Code v2.1.83で CwdChangedFileChanged という2つのHookイベントが追加された。これまでのHooks(PreToolUse/PostToolUse/Stop)がツール操作に反応するのに対し、この2つは環境の変化に反応する。


CwdChanged と FileChanged の概要

イベント 発火タイミング 主なユースケース
CwdChanged カレントディレクトリが変わったとき プロジェクト固有の環境変数を切替・direnv連携
FileChanged ファイルが変更されたとき 設定ファイルの変更を検知して再読み込み

① CwdChanged——ディレクトリ移動で環境を切り替える

複数プロジェクトを切り替えながら開発しているとき、プロジェクトごとに必要な環境変数(AWSプロファイル・APIキー・Node.jsバージョンなど)が異なる場合がある。

CwdChanged を使うと、ディレクトリを移動した瞬間に環境を自動切替できる。

settings.json の設定

{
  "hooks": {
    "CwdChanged": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/on_cwd_changed.py"
          }
        ]
      }
    ]
  }
}

フックに渡されるデータ

{
  "cwd": "/Users/yourname/projects/new-project"
}

実装例:プロジェクトに応じてAWSプロファイルを切り替える

# ~/.claude/hooks/on_cwd_changed.py
import json
import sys
import os
import subprocess

input_data = json.loads(sys.stdin.read())
cwd = input_data.get("cwd", "")

# プロジェクトパスとAWSプロファイルのマッピング
profile_map = {
    "/Users/yourname/projects/prod-app": "prod",
    "/Users/yourname/projects/dev-app": "dev",
    "/Users/yourname/projects/staging-app": "staging",
}

for path, profile in profile_map.items():
    if cwd.startswith(path):
        # 環境変数を設定するシェルスクリプトを出力
        print(f"AWS_PROFILE={profile} に切り替えました")
        # 実際の環境変数設定はshell hookで行う
        sys.exit(0)

print(f"ディレクトリ変更: {cwd}")

② FileChanged——設定ファイルの変更を検知する

FileChanged は特定のファイルが変更されたときに発火する。設定ファイルの変更をClaude Codeのセッション中にリアルタイムで反映させたい場合に使える。

settings.json の設定

{
  "hooks": {
    "FileChanged": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/on_file_changed.py"
          }
        ]
      }
    ]
  }
}

フックに渡されるデータ

{
  "file": "/Users/yourname/projects/myapp/.env"
}

実装例:.envファイルの変更を通知する

# ~/.claude/hooks/on_file_changed.py
import json
import sys
import os

input_data = json.loads(sys.stdin.read())
changed_file = input_data.get("file", "")

# .envファイルが変更されたら通知
if changed_file.endswith(".env") or changed_file.endswith(".env.local"):
    print(json.dumps({
        "type": "notification",
        "message": f".envファイルが変更されました: {os.path.basename(changed_file)}"
    }))
    sys.exit(0)

# CLAUDE.mdが変更されたら通知
if os.path.basename(changed_file) == "CLAUDE.md":
    print(json.dumps({
        "type": "notification",
        "message": "CLAUDE.mdが更新されました。指示が変わっている可能性があります。"
    }))
    sys.exit(0)

direnv的な環境管理との比較

CwdChanged は direnv の動作に近い。ただし、Claude Codeプロセス自身の環境変数を書き換えることはできない点が異なる。

direnv CwdChanged Hook
動作するタイミング cdコマンド実行時 Claude Code内でcwd変更時
環境変数を変える シェル自体に反映 Hookスクリプト内での処理のみ
主な用途 シェル全体の環境管理 Claude Codeセッション内の反応処理

CwdChanged Hookは「ディレクトリが変わった」という通知を受け取る仕組みであり、シェル環境変数を直接書き換えるものではない。ログ記録・通知送信・外部スクリプト起動などの用途に向いている。


PreToolUse/PostToolUse との違い

これまでのHookイベントと今回追加されたイベントを整理すると:

イベント 何に反応するか
PreToolUse ツールが実行される直前
PostToolUse ツールが実行された直後
Stop Claude Codeが応答を終了したとき
CwdChanged カレントディレクトリが変わったとき (v2.1.83新規)
FileChanged ファイルが変更されたとき (v2.1.83新規)

PreToolUse/PostToolUseはClaudeの操作に割り込む用途、CwdChanged/FileChangedは環境の変化を監視する用途と、役割が明確に分かれている。


まとめ

  • CwdChanged はディレクトリ移動時に発火し、プロジェクト切替時の環境管理に使える
  • FileChanged はファイル変更時に発火し、設定ファイルの変更検知に使える
  • どちらも「Claude Codeの操作」ではなく「環境の変化」に反応するイベント
  • PreToolUse/PostToolUseと組み合わせることで、より細かいClaude Code自動化が実現できる

第7回:HooksとSkillsで安全なスキルを作る——セキュリティ設計第9回:コンテキスト管理の技術——トークンを無駄にしない