Documentation Index
Fetch the complete documentation index at: https://docs.qoder.com/llms.txt
Use this file to discover all available pages before exploring further.
Hooksは、Qoder CLIの重要なポイントでAgentのメイン実行フローに介入しながら、CLIとの疎結合を保つ仕組みです。主な用途として、ツール実行前の危険な操作の遮断、タスク完了後のデスクトップ通知送信、ファイル書き込み後の自動lintなどが挙げられます。
HooksはJSON設定ファイルで定義されるため、コードを変更する必要はありません。設定ファイルを編集するだけで即座に有効になります。
クイックスタート
以下の例では、HookでAgentがrm -rfを実行しようとした際に自動的に阻止する危険なコマンド遮断の実装を示します。
ステップ1:スクリプトを作成する
mkdir -p ~/.qoder/hooks
cat > ~/.qoder/hooks/block-rm.sh << 'EOF'
#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command')
if echo "$command" | grep -q 'rm -rf'; then
echo "危険なコマンドをブロックしました: $command" >&2
exit 2
fi
exit 0
EOF
chmod +x ~/.qoder/hooks/block-rm.sh
ステップ2:設定ファイルを編集する
~/.qoder/settings.jsonに以下を追加します:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.qoder/hooks/block-rm.sh"
}
]
}
]
}
}
ステップ3:動作を確認する
Qoder CLIを起動し、Agentにrm -rfを含むコマンドを実行させてみてください。Hookが実行を阻止し、Agentに通知します。
設定ファイルの場所
Hook設定は以下の3つのファイルから読み込まれ、3段階の設定がマージされて実行されます:
~/.qoder/settings.json # ユーザーレベル。すべてのプロジェクトに適用
${project}/.qoder/settings.json # プロジェクトレベル。現在のプロジェクトに適用。gitにコミットしてチームと共有可能
${project}/.qoder/settings.local.json # プロジェクトレベル(ローカル)。最高優先度。.gitignoreへの追加を推奨
設定フォーマット
{
"hooks": {
"イベント名": [
{
"matcher": "マッチ条件",
"hooks": [
{
"type": "command",
"command": "実行するコマンド",
"timeout": 60
}
]
}
]
}
}
フィールドの説明:
| フィールド | 必須 | 説明 |
|---|
type | はい | 固定値:"command" |
command | はい | 実行するシェルコマンド |
timeout | いいえ | タイムアウト秒数(デフォルト:60) |
matcher | いいえ | マッチ条件。省略するとすべてにマッチ |
1つのイベントに複数のmatcherグループを設定でき、各グループに複数のhookコマンドを含めることができます。
matcherのルール
matcherはhookのトリガー範囲をフィルタリングします。イベントごとにマッチする対象が異なります(各イベントの説明を参照)。
| 書き方 | 意味 | 例 |
|---|
省略または"*" | すべてにマッチ | すべてのツールでトリガー |
| 固定値 | 完全一致 | "Bash" はBashツールのみマッチ |
|区切り | 複数値にマッチ | "Write|Edit" はWriteまたはEditにマッチ |
| 正規表現 | 正規表現マッチ | "mcp__.*" はすべてのMCPツールにマッチ |
Hookスクリプトの書き方
Hookスクリプトはstdinを通してJSON入力を受け取り、exit codeとstdoutによって動作を制御します。本セクションではすべてのイベントに共通する入出力フォーマットを説明します。各イベント固有の追加フィールドはサポートされるイベントを参照してください。
HookスクリプトはstdinからJSONデータを受け取ります。すべてのイベントに以下の共通フィールドが含まれます:
| フィールド | 説明 |
|---|
session_id | 現在のセッションID |
cwd | 現在の作業ディレクトリ |
hook_event_name | トリガーされたイベント名 |
イベントごとにこれらに加えて追加フィールドが付加されます(各イベントの説明を参照)。
jqを使った入力の解析例:
#!/bin/bash
input=$(cat)
tool_name=$(echo "$input" | jq -r '.tool_name')
Hook は exit code と stdout で動作を制御します。
exit code が基本動作を決定します:0 は成功、2 はブロック(stderr の内容が会話に注入、ブロックをサポートするイベントのみ有効)、その他の値は非ブロッキングエラーです。
stdout JSON(exit 0 の場合のみ解析)は一部のイベントに対して詳細な制御を提供します。サポートされるフィールドは各イベントの説明を参照してください。exit が 0 以外の場合、stdout は無視されます。
環境変数
Hookスクリプト実行時に以下の環境変数が利用できます:
| 変数 | 説明 |
|---|
QODER_PROJECT_DIR | 現在のプロジェクトの作業ディレクトリ |
サポートされるイベント
Qoder CLIは以下のHookイベントをサポートし、セッションライフサイクルの各段階をカバーしています。
SessionStart
セッション開始時にトリガーされます。
matcherの対象: セッションのソース
| matcher値 | トリガーシナリオ |
|---|
startup | 新しいセッション開始時 |
resume | 既存セッションの再開時 |
compact | コンテキスト圧縮完了後 |
追加入力フィールド:
{
"source": "startup",
"model": "Auto"
}
SessionEnd
セッション終了時にトリガーされます。
matcherの対象: 終了理由
| matcher値 | トリガーシナリオ |
|---|
prompt_input_exit | ユーザーが入力を終了(Ctrl+Dなど) |
other | その他の理由 |
追加入力フィールド:
{
"reason": "prompt_input_exit"
}
UserPromptSubmit
ユーザーが Prompt を送信した後、Agent が処理する前にトリガーされます。
追加入力フィールド:
{
"prompt": "ソート関数を書いてください"
}
ツール実行前にトリガーされます。ツールの実行を阻止できます。
matcherの対象: ツール名(例:Bash、Write、Edit、Read、Glob、Grep、MCPツール名はmcp__server__tool形式)
追加入力フィールド:
{
"tool_name": "Bash",
"tool_input": {"command": "rm -rf /tmp/build"},
"tool_use_id": "toolu_01ABC123"
}
ツール実行の阻止: exit code 2を返します。stderrの内容がエラーとしてAgentに返されます。完全な例はクイックスタートを参照してください。
PostToolUse
ツールが正常に実行された後にトリガーされます。
matcherの対象: ツール名
追加入力フィールド:
{
"tool_name": "Write",
"tool_input": {"file_path": "/path/to/file.ts", "content": "..."},
"tool_response": "File written successfully",
"tool_use_id": "toolu_01ABC123"
}
PostToolUseFailure
ツールの実行が失敗した後にトリガーされます。
matcherの対象: ツール名
追加入力フィールド:
{
"tool_name": "Bash",
"tool_input": {"command": "npm test"},
"tool_use_id": "toolu_01ABC123",
"error": "Command exited with non-zero status code 1",
"is_interrupt": false
}
Stop
Agentがレスポンスを完了した後(メインAgent、保留中のツール呼び出しがない状態)にトリガーされます。Agentの停止を阻止して、作業を継続させることができます。
Agentの停止を阻止する: exit code 2を返します。stderrの内容がメッセージとして会話に注入され、Agentが作業を続けます。
SubagentStart / SubagentStop
サブAgentの起動時と完了時にトリガーされます。SubagentStopはStopと同様で、サブAgentの停止を阻止できます。
matcherの対象: Agentタイプ名
追加入力フィールド:
{
"agent_id": "a1b2c3d4",
"agent_type": "task"
}
PreCompact
コンテキスト圧縮前にトリガーされます。
matcherの対象: トリガー方法
| matcher値 | トリガーシナリオ |
|---|
manual | ユーザーが手動で/compactを実行 |
auto | コンテキストウィンドウが満杯になった際に自動トリガー |
追加入力フィールド:
{
"trigger": "manual",
"custom_instructions": "すべてのツール呼び出し結果を保持する"
}
Notification
通知イベントがトリガーされます(権限リクエスト、タスク完了など)。
matcherの対象: 通知タイプ
| matcher値 | トリガーシナリオ |
|---|
permission | 権限リクエスト通知 |
result | Agentの結果通知 |
追加入力フィールド:
{
"message": "Agent is requesting permission to run: rm -rf node_modules",
"title": "Permission Required",
"notification_type": "permission"
}
PermissionRequest
ツールの実行にユーザーの認可が必要な際にトリガーされます。
matcherの対象: ツール名
追加入力フィールド:
{
"tool_name": "Bash",
"tool_input": {"command": "rm -rf node_modules"}
}
実用的な使用例
デスクトップ通知
Agentがタスクを完了したり認可が必要な際にデスクトップ通知をポップアップ表示します。
スクリプト ~/.qoder/hooks/notify.sh(macOS):
#!/bin/bash
input=$(cat)
message=$(echo "$input" | jq -r '.message')
if echo "$message" | grep -q "^Agent"; then
osascript -e 'display notification "タスクが完了しました" with title "Qoder CLI"'
else
osascript -e 'display notification "タスクに認可が必要です" with title "Qoder CLI"'
fi
exit 0
設定:
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "~/.qoder/hooks/notify.sh"
}
]
}
]
}
}
ファイル書き込み後の自動Lint
Agentがファイルを書き込みまたは編集するたびに、自動的にlintチェックを実行します。
スクリプト ${project}/.qoder/hooks/auto-lint.sh:
#!/bin/bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
# JS/TSファイルのみチェック
case "$file_path" in
*.js|*.ts|*.jsx|*.tsx)
npx eslint "$file_path" --fix 2>/dev/null
;;
esac
exit 0
設定:イベント PostToolUse、matcher Write|Edit、command .qoder/hooks/auto-lint.sh。
Agentの作業を継続させる
Agentが停止した際に未完了のタスクがないか確認し、あればメッセージを注入してAgentに作業を続けさせます。
スクリプト ~/.qoder/hooks/check-continue.sh:
#!/bin/bash
# コミットされていないgitの変更を確認
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
echo "コミットされていない変更が検出されました。git commitを完了してください" >&2
exit 2
fi
exit 0
設定:イベント Stop、command ~/.qoder/hooks/check-continue.sh。