原文(日本語に翻訳)
PreToolUse フックに "defer" 権限決定を追加 — ヘッドレスセッションはツール呼び出しで一時停止し、-p --resume で再開してフックを再評価できます
原文(英語)
Added "defer" permission decision to PreToolUse hooks — headless sessions can pause at a tool call and resume with -p --resume to have the hook re-evaluate
概要
PreToolUse フックで新たに "defer" という権限決定が使用できるようになりました。これにより、ヘッドレス(-p フラグ)セッション中にツール呼び出しを一時停止し、外部処理や人間によるレビューを挟んだ後、-p --resume で再開してフックに再評価させることができます。CI/CD パイプラインや自動化ワークフローで、特定のツール呼び出しに対して動的な承認フローを組み込む際に非常に有用です。
基本的な使い方
PreToolUse フックから "defer" を返すことで、セッションを一時停止できます。
json
// settings.json のフック設定例
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "check-requires-approval.sh"
}
]
}
]
}
}bash
# check-requires-approval.sh の例
#!/bin/bash
TOOL_INPUT="$CLAUDE_TOOL_INPUT"
# 危険なコマンドが含まれていたら defer を返す
if echo "$TOOL_INPUT" | grep -q "rm -rf\|DROP TABLE"; then
echo '{"decision": "defer", "reason": "危険なコマンドのため手動承認が必要です"}'
exit 0
fi
# 通常のコマンドは allow
echo '{"decision": "allow"}'セッションの再開
bash
# 最初のヘッドレス実行(deferで一時停止される)
claude -p "本番データベースをクリーンアップしてください" --session-id my-session
# 外部承認後に再開
claude -p --resume my-session実践例
CI/CDパイプラインでの承認フロー
bash
#!/bin/bash
# pre-tool-hook.sh
TOOL_NAME="$CLAUDE_TOOL_NAME"
TOOL_INPUT="$CLAUDE_TOOL_INPUT"
SESSION_ID="$CLAUDE_SESSION_ID"
# 本番環境へのデプロイコマンドは defer
if echo "$TOOL_INPUT" | grep -q "deploy.*production\|kubectl.*prod"; then
# Slack通知やチケット作成などの処理
notify-slack "承認が必要: $TOOL_INPUT (セッション: $SESSION_ID)"
echo '{"decision": "defer", "reason": "本番デプロイは手動承認が必要"}'
exit 0
fi
echo '{"decision": "allow"}'yaml
# GitHub Actions での利用例
- name: Run Claude with approval flow
run: |
# 初回実行(deferで停止する可能性あり)
claude -p "$PROMPT" --session-id $SESSION_ID || true
# 承認後に再開
claude -p --resume $SESSION_ID外部審査システムとの統合
python
# approve_and_resume.py
import subprocess
import json
def check_approval(session_id: str, tool_input: str) -> bool:
# 外部審査システムへ問い合わせ
response = requests.post(
"https://approval-system.internal/check",
json={"session_id": session_id, "input": tool_input}
)
return response.json()["approved"]
def resume_session(session_id: str):
subprocess.run(["claude", "-p", "--resume", session_id])
# メイン処理
if check_approval(session_id, tool_input):
resume_session(session_id)注意点
"defer"は-p(ヘッドレス)モードでのみ機能します。インタラクティブセッションでは動作が異なります--resumeで再開した際、フックが再度実行されます。無限ループを防ぐため、承認済みのセッションIDを記録しておくことを推奨します- ツール入力が64KBを超える場合の
--resumeハングバグは v2.1.89 で修正済みです - セッションIDの管理はユーザー側の責任となります