Claude Code Hooks実装ハンズオン:実戦で学ぶ開発自動化【2025年7月最新実践編】¶
はじめに¶
本記事は Claude Code Hooks革命:開発ワークフロー自動化の新次元【2025年7月最新】 の実践編として、実際のコード例とハンズオン体験を通じてClaude Code Hooksの導入・実装を完全マスターできる内容となっています。
理論から実装まで、今すぐプロジェクトで活用できる具体的なコード例と設定手順を提供します。
この記事のポイント¶
実際のコード実装
コピペで即使える設定ファイルとスクリプト例
エラー対処法
実際に発生するエラーとその解決方法を網羅
プロジェクト別設定
フレームワーク・言語別の最適化設定例
段階的導入
リスクを最小化した導入戦略とロールバック方法
🚀 ハンズオン1:基本的なHooks設定¶
環境準備¶
まず、Claude Code Hooksの設定ディレクトリを作成します。
# Claude Code設定ディレクトリ作成
mkdir -p ~/.claude
# 設定ファイルの初期化
touch ~/.claude/settings.json
推奨される設定方法
公式推奨: 設定ファイルの直接編集よりも、Claude Codeの/hooksインタラクティブUIコマンドの使用を推奨します。
# Claude Code起動後に以下のコマンドを実行
/hooks
この方法により、構文エラーのリスクを最小化し、GUI経由で安全に設定を管理できます。ただし、本記事では学習目的で設定ファイルの構造を詳しく解説します。
最初のHook:シンプルなファイル変更通知¶
{
"hooks": {
"PostToolUse": [
{
"name": "File Change Notification",
"condition": {
"tool_name": "edit_file"
},
"hooks": [
{
"type": "command",
"command": "echo '📝 File modified: $CLAUDE_FILE_PATHS'"
}
]
}
]
}
}
設定確認とテスト¶
# Claude Codeでテストファイルを作成
claude-code "Create a simple test.txt file with hello world"
# 出力例:
# 📝 File modified: /path/to/test.txt
デバッグのコツ
Hooksが動作しない場合は、claude-code --debug モードで実行すると詳細ログが確認できます。
🐍 ハンズオン2:Python開発環境の完全自動化¶
プロジェクト構造¶
my-python-project/
├── src/
│ ├── main.py
│ └── utils.py
├── tests/
│ └── test_main.py
├── requirements.txt
├── setup.cfg
└── pyproject.toml
段階的Hook設定¶
Step 1: 基本フォーマット¶
{
"hooks": {
"PostToolUse": [
{
"name": "Python Basic Format",
"condition": {
"tool_name": "edit_file",
"files_changed": ["*.py"]
},
"hooks": [
{
"type": "command",
"command": "echo \"🐍 Formatting Python file: $CLAUDE_FILE_PATHS\" && black $CLAUDE_FILE_PATHS && if [ $? -eq 0 ]; then echo \"✅ Black formatting completed\"; else echo \"❌ Black formatting failed\"; exit 1; fi"
}
]
}
]
}
}
Step 2: Import整理とリンティング¶
{
"hooks": {
"PostToolUse": [
{
"name": "Python Full Quality Check",
"condition": {
"tool_name": "edit_file",
"files_changed": ["*.py"]
},
"hooks": [
{
"type": "command",
"command": "echo \"🔍 Python quality check for: $CLAUDE_FILE_PATHS\" && echo \" ↳ Sorting imports...\" && isort $CLAUDE_FILE_PATHS --check-only --diff; if [ $? -ne 0 ]; then echo \" ↳ Applying import sort...\" && isort $CLAUDE_FILE_PATHS; fi && echo \" ↳ Running flake8...\" && flake8 $CLAUDE_FILE_PATHS --max-line-length=88 --extend-ignore=E203,W503 && echo \" ↳ Type checking with mypy...\" && mypy $CLAUDE_FILE_PATHS --ignore-missing-imports && echo \"✅ Python quality check completed\""
}
]
}
]
}
}
Step 3: テスト自動実行¶
[[hooks]]
name = "Python Test Runner"
event = "PostToolUse"
run_in_background = true
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["src/**/*.py", "tests/**/*.py"]
command = """
echo "🧪 Running Python tests..."
# 関連するテストファイルを特定
test_files=$(find tests/ -name "*test*.py" 2>/dev/null)
if [ -n "$test_files" ]; then
# 変更されたファイルに関連するテストのみ実行
pytest -xvs $test_files --tb=short
# カバレッジレポート生成
if command -v coverage >/dev/null 2>&1; then
echo "📊 Generating coverage report..."
coverage run -m pytest $test_files
coverage report --show-missing
fi
else
echo "ℹ️ No test files found, skipping test execution"
fi
"""
実際の使用例¶
# src/main.py を作成
def calculate_fibonacci(n: int) -> int:
"""フィボナッチ数列のn番目を計算"""
if n <= 1:
return n
return calculate_fibonacci(n-1) + calculate_fibonacci(n-2)
def main():
result = calculate_fibonacci(10)
print(f"Fibonacci(10) = {result}")
if __name__ == "__main__":
main()
Claude Codeでこのファイルを作成すると、自動的に以下が実行されます:
- Blackによるフォーマット適用
- isortによるimport整理
- flake8による静的解析
- mypyによる型チェック
- pytest実行(バックグラウンド)
⚛️ ハンズオン3:React/TypeScript開発環境¶
Next.js プロジェクト向け設定¶
[[hooks]]
name = "React TypeScript Quality"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.ts", "*.tsx", "*.js", "*.jsx"]
command = """
echo "⚛️ React/TypeScript quality check: $CLAUDE_FILE_PATHS"
# Prettierフォーマット
echo " ↳ Formatting with Prettier..."
prettier --write $CLAUDE_FILE_PATHS
# ESLint チェック
echo " ↳ Linting with ESLint..."
eslint --fix $CLAUDE_FILE_PATHS
# TypeScript型チェック
echo " ↳ Type checking..."
tsc --noEmit --skipLibCheck
echo "✅ React/TypeScript check completed"
"""
コンポーネント特化Hook¶
[[hooks]]
name = "React Component Validation"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["src/components/**/*.tsx", "src/pages/**/*.tsx"]
command = """
echo "🧩 Validating React component: $CLAUDE_FILE_PATHS"
# React特有のルールチェック
echo " ↳ React hooks validation..."
eslint $CLAUDE_FILE_PATHS --rule 'react-hooks/rules-of-hooks: error'
# コンポーネントテスト実行
component_name=$(basename $CLAUDE_FILE_PATHS .tsx)
test_file="src/components/__tests__/${component_name}.test.tsx"
if [ -f "$test_file" ]; then
echo " ↳ Running component tests..."
npm test -- --testPathPattern="$test_file" --watchAll=false
fi
# Storybookビルドテスト(storiesファイルが存在する場合)
stories_file="src/components/${component_name}.stories.tsx"
if [ -f "$stories_file" ]; then
echo " ↳ Validating Storybook stories..."
npm run build-storybook --quiet
fi
echo "✅ React component validation completed"
"""
🔒 ハンズオン4:セキュリティ強化設定¶
Git Secrets統合¶
[[hooks]]
name = "Security Secret Scan"
event = "PreToolUse"
[hooks.matcher]
tool_name = "edit_file"
command = """
echo "🔒 Security scan for: $CLAUDE_FILE_PATHS"
# Git secretsによるスキャン
if command -v git-secrets >/dev/null 2>&1; then
echo " ↳ Scanning for secrets..."
git secrets --scan $CLAUDE_FILE_PATHS
if [ $? -ne 0 ]; then
echo "🚨 Secret detected! Operation blocked."
exit 1
fi
fi
# 追加のパターンチェック
echo " ↳ Additional pattern checks..."
for file in $CLAUDE_FILE_PATHS; do
# APIキーパターンチェック
if grep -qE "api[_-]?key\s*=\s*['\"][^'\"]{10,}['\"]" "$file"; then
echo "🚨 Potential API key found in $file"
exit 1
fi
# AWS認証情報チェック
if grep -qE "AKIA[0-9A-Z]{16}" "$file"; then
echo "🚨 AWS Access Key found in $file"
exit 1
fi
done
echo "✅ Security scan passed"
"""
本番環境保護¶
[[hooks]]
name = "Production Environment Protection"
event = "PreToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["prod/**", "production/**", "*.prod.*", "deploy/**", "terraform/**"]
command = """
echo "🛡️ Production file modification detected!"
echo "Files: $CLAUDE_FILE_PATHS"
# インタラクティブ確認
echo "⚠️ You are about to modify production-related files."
echo "Are you sure you want to continue? (Type 'yes' to confirm)"
read -r confirmation
if [ "$confirmation" != "yes" ]; then
echo "❌ Operation cancelled for safety"
exit 1
fi
# 追加の安全チェック
current_branch=$(git branch --show-current)
if [ "$current_branch" = "main" ] || [ "$current_branch" = "master" ]; then
echo "🚨 WARNING: You are on the main branch!"
echo "Consider creating a feature branch for production changes."
echo "Continue anyway? (Type 'CONFIRM' to proceed)"
read -r final_confirmation
if [ "$final_confirmation" != "CONFIRM" ]; then
echo "❌ Operation cancelled"
exit 1
fi
fi
echo "✅ Production modification approved"
"""
📊 ハンズオン5:高度なワークフロー統合¶
GitHub Actions連携¶
[[hooks]]
name = "GitHub Actions Integration"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = [".github/workflows/**/*.yml", ".github/workflows/**/*.yaml"]
command = """
echo "🔄 GitHub Actions workflow validation: $CLAUDE_FILE_PATHS"
# YAML構文チェック
echo " ↳ YAML syntax validation..."
for file in $CLAUDE_FILE_PATHS; do
if command -v yamllint >/dev/null 2>&1; then
yamllint "$file"
else
python -c "import yaml; yaml.safe_load(open('$file'))"
fi
done
# GitHub Actions特有の構文チェック
echo " ↳ GitHub Actions syntax check..."
if command -v act >/dev/null 2>&1; then
act --list
fi
echo "✅ GitHub Actions validation completed"
"""
Docker統合¶
[[hooks]]
name = "Docker Build Validation"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["Dockerfile", "docker-compose.yml", "docker-compose.yaml"]
command = """
echo "🐳 Docker configuration validation: $CLAUDE_FILE_PATHS"
for file in $CLAUDE_FILE_PATHS; do
case "$file" in
*Dockerfile*)
echo " ↳ Validating Dockerfile..."
docker build --no-cache -t temp-validation -f "$file" .
docker rmi temp-validation
;;
*docker-compose*)
echo " ↳ Validating docker-compose..."
docker-compose -f "$file" config
;;
esac
done
echo "✅ Docker validation completed"
"""
🔧 トラブルシューティング¶
よくある問題と解決法¶
1. Hookが実行されない¶
# デバッグモードで実行
claude-code --debug "Edit a test file"
# 設定ファイルの構文チェック
# JSONファイルの場合はjqでチェック
# jq empty ~/.claude/settings.json
2. 環境変数が認識されない¶
# 環境変数を明示的に渡す
[[hooks]]
name = "Environment Variable Fix"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
command = """
export PATH="$PATH:/usr/local/bin"
export PYTHONPATH="$PYTHONPATH:$(pwd)/src"
your-command $CLAUDE_FILE_PATHS
"""
3. パフォーマンス問題¶
# 長時間実行されるタスクはバックグラウンドで
[[hooks]]
name = "Performance Optimized"
event = "PostToolUse"
run_in_background = true # これを追加
timeout = 30 # タイムアウト設定
[hooks.matcher]
tool_name = "edit_file"
command = "long-running-task $CLAUDE_FILE_PATHS"
デバッグ用Hook¶
[[hooks]]
name = "Debug Information"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
command = """
echo "🔍 Debug Information:"
echo " Working Directory: $(pwd)"
echo " User: $(whoami)"
echo " Files: $CLAUDE_FILE_PATHS"
echo " Environment: $(env | grep CLAUDE)"
echo " Git Branch: $(git branch --show-current 2>/dev/null || echo 'not a git repo')"
"""
🎯 プロジェクト別最適化設定¶
Django プロジェクト¶
[[hooks]]
name = "Django Development"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
# Django特有の処理
if [ -f "manage.py" ]; then
echo "🐍 Django project detected"
# マイグレーション作成チェック
if echo $CLAUDE_FILE_PATHS | grep -q "models.py"; then
echo " ↳ Model changes detected, checking migrations..."
python manage.py makemigrations --dry-run --verbosity=0
if [ $? -ne 0 ]; then
echo " ↳ Creating migrations..."
python manage.py makemigrations
fi
fi
# Django アプリケーションのテスト実行
echo " ↳ Running Django tests..."
python manage.py test --parallel --keepdb
fi
"""
Node.js/Express プロジェクト¶
[[hooks]]
name = "Node.js Express Development"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.js", "*.ts"]
command = """
if [ -f "package.json" ]; then
echo "📦 Node.js project detected"
# 依存関係チェック
if echo $CLAUDE_FILE_PATHS | grep -q "package.json"; then
echo " ↳ Package.json modified, checking dependencies..."
npm audit
npm outdated
fi
# ESLint & Prettier
echo " ↳ Code quality checks..."
npm run lint --if-present
npm run format --if-present
# テスト実行
echo " ↳ Running tests..."
npm test --if-present
fi
"""
📈 パフォーマンス最適化¶
条件付き実行¶
[[hooks]]
name = "Conditional Execution"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
# ファイルサイズチェック
file_size=$(wc -c < $CLAUDE_FILE_PATHS)
if [ $file_size -gt 10000 ]; then
echo "⚠️ Large file detected (${file_size} bytes), skipping expensive checks"
exit 0
fi
# 通常の処理
black $CLAUDE_FILE_PATHS
flake8 $CLAUDE_FILE_PATHS
"""
並列実行¶
[[hooks]]
name = "Parallel Processing"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
echo "🔄 Starting parallel quality checks..."
# 並列実行でパフォーマンス向上
(
echo " ↳ Black formatting..." && black $CLAUDE_FILE_PATHS
) &
(
echo " ↳ Import sorting..." && isort $CLAUDE_FILE_PATHS
) &
(
echo " ↳ Linting..." && flake8 $CLAUDE_FILE_PATHS
) &
# 全てのバックグラウンドジョブの完了を待つ
wait
echo "✅ Parallel processing completed"
"""
🔄 段階的導入戦略¶
Phase 1: 監視のみ¶
[[hooks]]
name = "Monitor Only - Phase 1"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
echo "👀 MONITOR MODE: File modified - $CLAUDE_FILE_PATHS"
echo " ↳ Would run: black, flake8, pytest"
echo " ↳ This is monitor-only mode - no actions taken"
"""
Phase 2: 自動修正¶
[[hooks]]
name = "Auto Fix - Phase 2"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
echo "🔧 AUTO-FIX MODE: $CLAUDE_FILE_PATHS"
black $CLAUDE_FILE_PATHS
isort $CLAUDE_FILE_PATHS
echo "✅ Automatic fixes applied"
"""
Phase 3: 完全自動化¶
[[hooks]]
name = "Full Automation - Phase 3"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
file_paths = ["*.py"]
command = """
echo "🚀 FULL AUTOMATION: $CLAUDE_FILE_PATHS"
black $CLAUDE_FILE_PATHS
isort $CLAUDE_FILE_PATHS
flake8 $CLAUDE_FILE_PATHS
pytest --tb=short -x
echo "✅ Full automation pipeline completed"
"""
💡 実用的なTips¶
1. 設定ファイルの分割管理¶
# 設定を分割して管理
mkdir -p ~/.claude/hooks
# JSON形式での設定管理(申し訳ございませんが、現在のJSON形式ではファイル分割をサポートしていません)
# 最新の公式仕様では ~/.claude/settings.json にすべての設定を全て記載します
2. プロジェクト固有設定¶
# プロジェクトディレクトリでの条件分岐
[[hooks]]
name = "Project Specific"
event = "PostToolUse"
[hooks.matcher]
tool_name = "edit_file"
command = """
project_root=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
project_name=$(basename "$project_root")
case "$project_name" in
"my-backend-api")
echo "🔙 Backend API project detected"
# API specific hooks
;;
"my-frontend-app")
echo "🎨 Frontend app project detected"
# Frontend specific hooks
;;
*)
echo "📁 Generic project"
# Default hooks
;;
esac
"""
3. 緊急時の無効化¶
# Hooksを一時的に無効化
export CLAUDE_HOOKS_DISABLED=1
claude-code "Emergency edit without hooks"
# または設定ファイルをリネーム
mv ~/.claude/settings.json ~/.claude/settings.json.disabled
まとめ¶
Claude Code Hooksの実装を通じて、以下の実践的スキルが身につきました:
- 段階的導入: リスクを最小化した安全な導入方法
- 言語別最適化: Python、JavaScript/TypeScript、Docker等の専用設定
- セキュリティ強化: 本番環境保護とシークレット検出の実装
- トラブルシューティング: 実際の問題とその解決法
- パフォーマンス最適化: 並列実行と条件付き実行による高速化
次のステップ
この実装ハンズオンで基礎を身につけたら、Claude Code Hooks革命:開発ワークフロー自動化の新次元【2025年7月最新】 で紹介した高度な機能やGitHub Copilot Agent Modeとの統合に挑戦してみてください。
重要な注意点
本番環境での導入前に、必ず開発環境での十分なテストを実施してください。また、チーム全体での設定統一とドキュメント化を忘れずに行いましょう。