Windsurf Hooks 入門:AI 開発を自動化する全能テクニック
Windsurf の強力な AI エージェント "Cascade" には、「Cascade Hooks (Beta)」 という隠れた(しかし公式の)機能があります。
これは「AI がファイルを読んだとき」「コマンドを実行したとき」などのイベントをフックして、任意のスクリプトを自動実行できる 仕組みです。
Cursor の .cursorrules や Hooks に似ていますが、Windsurf ではシェルスクリプトや Python を直接呼び出せるため、OS レベルでの自由な自動化 が可能です。
この記事では、言語やフレームワークを問わず使える 「汎用的な Hooks 設定とスクリプト」 を紹介します。
Hooks の基本
Hooks は .windsurf/hooks.json という設定ファイルで管理します。
Cascade が特定のアクションを行うと、設定されたコマンドに JSON 形式のイベント情報 が標準入力で渡されます。
利用できる主なイベント
- pre_read_code / post_read_code: AI がファイルを読む前後
- pre_write_code / post_write_code: AI がファイルを編集する前後
- pre_run_command / post_run_command: AI がターミナルコマンドを実行する前後
準備:設定ファイルの作成
まずはプロジェクトのルート(または ~/.codeium/windsurf/)に設定ディレクトリを作ります。
.windsurf/
├── hooks.json # 設定のエントリーポイント
└── hooks/ # スクリプトを置く場所
レシピ 1: 保存時に自動フォーマット(言語汎用版)
AI がコードを修正した直後に、そのファイルの拡張子に応じて適切なフォーマッタを実行します。
これを入れておくと、AI 特有のインデント崩れやスタイル違反を気にせず開発できます。
.windsurf/hooks.json
{
"hooks": {
"post_write_code": [
{
"command": "bash .windsurf/hooks/format.sh",
"show_output": false
}
]
}
}
.windsurf/hooks/format.sh
#!/usr/bin/env bash
# 標準入力からコンテキストを取得
input=$(cat)
# jq で変更されたファイルのパスを抽出
file_path=$(echo "$input" | jq -r '.tool_info.file_path')
case "$file_path" in
# JavaScript / TypeScript / JSON / Markdown
*.js|*.jsx|*.ts|*.tsx|*.json|*.md)
if command -v prettier >/dev/null 2>&1; then
npx prettier --write "$file_path"
fi
;;
# Python
*.py)
if command -v black >/dev/null 2>&1; then
black "$file_path"
fi
;;
# Go
*.go)
if command -v gofmt >/dev/null 2>&1; then
gofmt -w "$file_path"
fi
;;
# Rust
*.rs)
if command -v rustfmt >/dev/null 2>&1; then
rustfmt "$file_path"
fi
;;
esac
exit 0
レシピ 2: 長時間コマンドの完了通知
AI に「テスト全部回して」や「ビルドして」と頼んだ後、別の作業をしていても完了に気づけるようにします。
.windsurf/hooks.json
{
"hooks": {
"post_run_command": [
{
"command": "python3 .windsurf/hooks/notify.py",
"show_output": false
}
]
}
}
.windsurf/hooks/notify.py (Python)
特定のキーワード(build, test, install 等)を含むコマンドが終わったときだけ通知を出します。
#!/usr/bin/env python3
import sys, json, subprocess, platform
data = json.loads(sys.stdin.read())
cmd = data.get("tool_info", {}).get("command_line", "")
# 通知対象にするコマンドのキーワード
WATCH_KEYWORDS = ["build", "test", "install", "docker-compose up"]
if any(k in cmd for k in WATCH_KEYWORDS):
message = f"Command finished: {cmd}"
if platform.system() == "Darwin": # macOS
subprocess.run(["osascript", "-e", f'display notification "{message}" with title "Windsurf Cascade"'])
elif platform.system() == "Windows": # Windows (PowerShell)
subprocess.run(["powershell", "-Command", f"New-BurntToastNotification -Text '{message}'"], shell=True)
# Linux なら notify-send など
sys.exit(0)
レシピ 3: 機密ファイルの読み込みブロック(セキュリティ)
AI が誤って .env ファイルや SSH 鍵などを読み込もうとした場合に、強制的にブロックします。
企業利用や配信中の利用で特に有効です。
.windsurf/hooks.json
{
"hooks": {
"pre_read_code": [
{
"command": "bash .windsurf/hooks/security-check.sh",
"show_output": true
}
]
}
}
.windsurf/hooks/security-check.sh
終了コード 1 (または非ゼロ) を返すと、Windsurf はそのアクションをキャンセルします。
#!/usr/bin/env bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_info.file_path')
# ブロックしたいファイル名のパターン
if [[ "$file_path" == *".env"* || "$file_path" == *".ssh"* || "$file_path" == *"aws/credentials"* ]]; then
echo "🚫 Access denied by Hooks: Sensitive file access is blocked."
exit 1 # ここでエラーを返すと、Cascade は読み込みに失敗する
fi
exit 0
レシピ 4: AI の行動ログ(監査用)
AI が「いつ」「どのファイルを」変更したかをログに残します。
Git の履歴だけでは追いきれない、AI との試行錯誤のプロセスを記録できます。
.windsurf/hooks.json
{
"hooks": {
"post_write_code": [
{ "command": "python3 .windsurf/hooks/logger.py" }
],
"post_run_command": [
{ "command": "python3 .windsurf/hooks/logger.py" }
]
}
}
.windsurf/hooks/logger.py
#!/usr/bin/env python3
import sys, json, datetime, os
LOG_FILE = os.path.expanduser("~/.windsurf/cascade_history.log")
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
data = json.loads(sys.stdin.read())
event = data.get("agent_action_name")
timestamp = datetime.datetime.now().isoformat()
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(f"[{timestamp}] {event}\n")
f.write(json.dumps(data, indent=2, ensure_ascii=False) + "\n")
f.write("-" * 40 + "\n")
sys.exit(0)
まとめ
Windsurf の Cascade Hooks は、「AI の行動に対するミドルウェア」 のようなものです。
- 品質担保: 自動フォーマット、Lint
- 効率化: 長時間タスクの通知
- 安全性: 機密ファイルへのアクセス制御
- 透明性: 行動ログの記録
これらを組み合わせることで、単なるコード生成ツールを超えた、自分好みの最強の開発パートナーを作ることができます。ぜひ試してみてください。
Discussion