> [!left-bubble] ![[colot-mini.webp]] > [[GitHub Copilot CLI]]の `/research` によるレポートです。 # GitHub Copilot CLI: agentStop / sessionEnd / sessionStart の違い ## Executive Summary `sessionStart`、`sessionEnd`、[[agentStop (GitHub Copilot)|agentStop]] はいずれも GitHub Copilot CLI の **hooks(フック)** システムで定義されたライフサイクルイベントである。これらはエージェントの動作中の異なるタイミングで発火し、カスタムシェルスクリプトを実行できる拡張ポイントを提供する。最大の違いは **スコープ(対象範囲)** にある。`sessionStart`/`sessionEnd` はセッション全体のライフサイクルに対応し、`agentStop` は個々のプロンプトへの応答完了時に発火する。 ## 概念の説明 ### フックシステムの全体像 GitHub Copilot CLI のフックシステムは、エージェントのワークフローの戦略的なポイントでカスタムシェルコマンドを実行できる仕組みである[^1]。フックは `.github/hooks/*.json` にJSON形式で定義し、各イベントに対して1つ以上のコマンドを登録できる[^2]。 利用可能なフックイベントの全体像は以下の通り: ``` セッション開始 (sessionStart) │ ├─ ユーザープロンプト送信 (userPromptSubmitted) │ │ │ ├─ ツール使用前 (preToolUse) ← 唯一「拒否」可能 │ ├─ ツール使用後 (postToolUse) │ │ ... (ツール使用の繰り返し) │ │ │ ├─ サブエージェント開始 (subagentStart) │ │ └─ サブエージェント完了 (subagentStop) │ │ │ └─ エージェント応答完了 (agentStop) ★ │ ├─ (次のプロンプト ... 同じサイクルの繰り返し) │ └─ セッション終了 (sessionEnd) ※ エラー発生時: errorOccurred (任意のタイミング) ``` --- ### sessionStart(セッション開始フック) **発火タイミング**: 新しいエージェントセッションが開始されたとき、または既存のセッションが再開(resume)されたとき[^1][^2]。 **入力JSON**: ```json { "timestamp": 1704614400000, "cwd": "/path/to/project", "source": "new", "initialPrompt": "Create a new feature" } ``` **主要フィールド**: | フィールド | 説明 | |-----------|------| | `timestamp` | Unixタイムスタンプ(ミリ秒) | | `cwd` | 現在の作業ディレクトリ | | `source` | `"new"`(新規)、`"resume"`(再開)、`"startup"` のいずれか | | `initialPrompt` | ユーザーの初期プロンプト(提供された場合) | **スコープ**: **セッション全体** — CLIの起動時、`/new` での新規セッション作成時、`--resume` でのセッション再開時に1回発火する[^3]。 **ユースケース**: - 開発環境の初期化 - セッション開始の監査ログ記録 - プロジェクト状態のバリデーション - 一時リソースのセットアップ **特筆事項**: v1.0.11で追加された `additionalContext` 機能により、sessionStartフックからの出力をエージェントの会話に注入できるようになった[^4]。また、`source` フィールドの値によってセッションの開始方法を判別でき、新規セッションと再開セッションで異なるロジックを実行可能[^3]。 --- ### [[sessionEnd (GitHub Copilot)|sessionEnd]](セッション終了フック) **発火タイミング**: エージェントセッションが完了または終了されたとき[^1][^2]。 **入力JSON**: ```json { "timestamp": 1704618000000, "cwd": "/path/to/project", "reason": "complete" } ``` **主要フィールド**: | フィールド | 説明 | |-----------|------| | `timestamp` | Unixタイムスタンプ(ミリ秒) | | `cwd` | 現在の作業ディレクトリ | | `reason` | `"complete"`, `"error"`, `"abort"`, `"timeout"`, `"user_exit"` のいずれか | **スコープ**: **セッション全体** — CLI終了時、`/clear`実行時、エラーによるセッション中断時などに1回発火する。 **ユースケース**: - 一時リソースのクリーンアップ - セッションレポートの生成・アーカイブ - セッション完了の通知送信 - `reason` に基づく条件付き処理(正常完了 vs エラー終了) **`reason` フィールドの値**: | 値 | 意味 | |---|------| | `complete` | 正常完了 | | `error` | エラーによる終了 | | `abort` | 中断 | | `timeout` | タイムアウト | | `user_exit` | ユーザーによる終了(`/exit`, Ctrl+C×2, Ctrl+D など) | --- ### agentStop(エージェント応答完了フック) **発火タイミング**: メインエージェントが1つのプロンプトへの応答を完了したとき[^1]。 **スコープ**: **プロンプト単位** — 1つのセッション内でユーザーが複数のプロンプトを送信した場合、各プロンプトの処理完了ごとに発火する。 **ユースケース**: - 各応答完了後のカスタム処理(ログ記録、状態更新など) - 下流システムへの通知 - 応答品質のチェック - サブエージェントとは別の、メインエージェントの活動終了の追跡 **関連フック — subagentStop**: `agentStop` のサブエージェント版。サブエージェント(`task` ツール経由で起動)が完了し、結果を親エージェントに返す前に発火する[^1]。 **導入時期**: `agentStop` と `subagentStop` は v1.0.2 (2026-03-07) で追加された[^5]。 --- ## 3つのフックの比較 | 特性 | sessionStart | sessionEnd | agentStop | |------|-------------|------------|-----------| | **スコープ** | セッション全体 | セッション全体 | プロンプト単位 | | **発火回数/セッション** | 1回 | 1回 | プロンプト数と同じ回数 | | **発火タイミング** | セッション開始・再開時 | セッション終了時 | 各プロンプトへの応答完了時 | | **入力に含まれる情報** | source, initialPrompt | reason | (エージェント応答のコンテキスト) | | **出力の処理** | 無視 | 無視 | 無視 | | **典型的な用途** | 環境初期化、ログ開始 | クリーンアップ、レポート生成 | 応答ごとのログ、状態更新 | ### 具体的な発火タイミングの図解 ``` copilot 起動 ↓ [sessionStart] ← 1回だけ発火 (source: "new") ↓ ユーザー: "バグを修正して" ↓ [userPromptSubmitted] ↓ エージェント: ツール実行、コード編集... ↓ [agentStop] ← 1回目の応答完了 ↓ ユーザー: "テストも追加して" ↓ [userPromptSubmitted] ↓ エージェント: テスト作成... ↓ [agentStop] ← 2回目の応答完了 ↓ ユーザー: /exit ↓ [sessionEnd] ← 1回だけ発火 (reason: "user_exit") ``` ## フックの設定方法 フック設定は以下の場所に配置できる[^2][^6]: 1. **リポジトリレベル**: `.github/hooks/*.json` 2. **ユーザーレベル**: `settings.json`, `settings.local.json`, `config.json` 3. **CLIレベル**: 作業ディレクトリから Git root まで各階層で検出 設定例: ```json { "version": 1, "hooks": { "sessionStart": [ { "type": "command", "bash": "./scripts/on-session-start.sh", "timeoutSec": 10 } ], "agentStop": [ { "type": "command", "bash": "echo \"Agent finished responding\" >> agent.log", "timeoutSec": 5 } ], "sessionEnd": [ { "type": "command", "bash": "./scripts/cleanup.sh", "timeoutSec": 60 } ] } } ``` **注意**: フックは同期的に実行され、エージェントの実行をブロックする。パフォーマンスへの影響を最小限にするため、実行時間は5秒以内に抑えることが推奨される[^2]。 ## Confidence Assessment - **高確信度**: `sessionStart`, `sessionEnd`, `agentStop` の基本的な役割と発火タイミングの違い。これらはGitHub公式ドキュメントで明確に定義されている。 - **高確信度**: フックの設定方法、入力JSONフォーマット、出力の扱い。公式リファレンスに記載あり。 - **中確信度**: `agentStop` の入力JSONの正確なフォーマット。公式ドキュメントの hooks configuration ページには `agentStop` の入力JSON例が記載されていないため、具体的なフィールドは不明。概念的な説明("About hooks" ページ)からスコープは確認済み。 - **低確信度**: `agentStop` と `sessionEnd` の内部実装の詳細。copilot-cli リポジトリのソースコードは非公開のため、実装レベルの確認はできていない。 ## Footnotes [^1]: [About hooks - GitHub Docs](https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-hooks) — フックタイプの定義と各イベントの説明 [^2]: [Hooks configuration - GitHub Docs](https://docs.github.com/en/copilot/reference/hooks-configuration) — フック設定リファレンス(入力JSON、出力フォーマット、ベストプラクティス) [^3]: [github/copilot-cli](https://github.com/github/copilot-cli) `changelog.md` — "Hooks fire correctly when resuming a previous session" (v1.0.6), "sessionStart hook additionalContext is now injected into the conversation" (v1.0.11) [^4]: [github/copilot-cli](https://github.com/github/copilot-cli) `changelog.md` v1.0.11 — "sessionStart hook additionalContext is now injected into the conversation" [^5]: [github/copilot-cli](https://github.com/github/copilot-cli) `changelog.md` v1.0.2 — "Add agentStop and subagentStop hooks to control agent completion" [^6]: [github/copilot-cli](https://github.com/github/copilot-cli) `changelog.md` v1.0.7 — "Support defining hooks in settings.json, settings.local.json, and config.json"