ClaudeにCLAUDE.md内でhooksへ移行した方が良さそうなものを移行してもらう
CLAUDE.mdに毎回実行を指示するよりhooksに入れた方が確実ではないかと思い、Claudeにhooks化を指示してみました。
hooksを使った処理は通常出力にTokenが掛からないこともあり、とりあえずhooks化と試しているところですが、数が多いと手間もかかってきます。
Claudeがあることだし、Claudeに任せてみることにしました。
Claudeにhooks化させる
可能だろうかと疑問でしたが、出力完了まで1プロンプトでした。
CLAUDE.md内でhooksに変えたほうが効率的な項目があればピックアップ
実際に生成されたhooksの例
プロジェクト設定に紐づいた場所があるため、コピペでは動かないかもしれません。
#!/bin/bash
# CLAUDE.md更新時にDeepLで日本語訳をCLAUDE_ja.mdに自動生成するフック
# 翻訳実行関数
perform_translation() {
# DeepLコマンドが存在するかチェック
if command -v deepl >/dev/null 2>&1; then
# システムのdeeplコマンドを使用
if deepl CLAUDE.md -o CLAUDE_ja.md 2>/dev/null; then
echo "✅ CLAUDE_ja.mdが正常に生成されました"
else
echo "❌ DeepL翻訳に失敗しました"
fi
elif [ -x "/opt/homebrew/bin/deepl" ]; then
# Homebrewでインストールされたdeeplを使用
if /opt/homebrew/bin/deepl CLAUDE.md -o CLAUDE_ja.md 2>/dev/null; then
echo "✅ CLAUDE_ja.mdが正常に生成されました"
else
echo "❌ DeepL翻訳に失敗しました"
fi
else
echo "⚠️ DeepLコマンドが見つかりません。手動でCLAUDE_ja.mdを更新してください。"
echo " 実行コマンド: deepl CLAUDE.md -o CLAUDE_ja.md"
fi
}
INPUT=$(cat)
# ツール入力を取得
TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input')
if [ "$TOOL_INPUT" = "null" ] || [ -z "$TOOL_INPUT" ]; then
exit 0
fi
# ファイルパスを取得(MUST utilize tool_input.file_path)
FILE_PATH=$(echo "$TOOL_INPUT" | jq -r '.file_path')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# CLAUDE.mdファイルが更新された場合のみ処理(CLAUDE_ja.mdは除外)
if [[ "$FILE_PATH" == *"CLAUDE.md" ]]; then
# プロジェクトルートディレクトリに移動
PROJECT_DIR=$(dirname "$FILE_PATH")
cd "$PROJECT_DIR" 2>/dev/null || exit 0
# CLAUDE.mdとCLAUDE_ja.mdのタイムスタンプを比較(DeepL制限回避)
if [ -f "CLAUDE_ja.md" ]; then
# 各ファイルの最終更新時間を取得(秒単位)
if command -v stat >/dev/null 2>&1; then
CLAUDE_MD_TIME=$(stat -f %m "CLAUDE.md" 2>/dev/null || stat -c %Y "CLAUDE.md" 2>/dev/null)
CLAUDE_JA_MD_TIME=$(stat -f %m "CLAUDE_ja.md" 2>/dev/null || stat -c %Y "CLAUDE_ja.md" 2>/dev/null)
# CLAUDE.mdの方が新しい場合のみ翻訳実行
if [ "$CLAUDE_MD_TIME" -gt "$CLAUDE_JA_MD_TIME" ]; then
echo "🌏 CLAUDE.mdの更新を検出。DeepLで日本語訳を生成中..."
perform_translation
else
echo "ℹ️ CLAUDE_ja.mdは既に最新です(翻訳をスキップ)"
fi
else
# statコマンドが利用できない場合は常に翻訳実行
echo "🌏 CLAUDE.mdの更新を検出。DeepLで日本語訳を生成中..."
perform_translation
fi
else
# CLAUDE_ja.mdが存在しない場合は翻訳実行
echo "🌏 CLAUDE_ja.mdが存在しません。DeepLで日本語訳を生成中..."
perform_translation
fi
fi
exit 0
実行されると以下の通り。
あとがき
問題としては、EventNameとMatcherに公式リファレンスには存在しないものを独自に指定してくることがあります。
/doctor
を実行すると指摘してくれるので、プロンプト実行後はチェックをしておきましょう。
Stopの処理でもstop_hook_active==true
の判定が使われなかったり、特定ファイル編集を対象にするhooksでtook_input.file_pathでファイル判定していないケースがあったり、生成されたスクリプトの確認は必須です。公式リファレンスを参照してなさそうな出力結果だったため、serenaメモリに公式リファレンスを追加してCLAUDE.mdにhooks生成時のルールを参照するように書き入れておくとよいでしょう。