## 概要
プロンプトが完了して人間の返答になったタイミングで[[ハーネス]]を整備したい。しかし、[[GitHub Copilot CLI]]はいつ[[フック (GitHub Copilot)|フック]]が実行されたのかが表面では分からず、動作も比較的不安定なので非効率である。
[[GitHub Copilot CLI]]にまとめてもらったレポートはあるが、これが信用たるものなのかは自信がない。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" />
<span class="link-card-v2-site-name">Minerva</span>
</div>
<div class="link-card-v2-title">
📰GitHub Copilot CLIにおけるagentStop、sessionEnd、sessionStartの違い
</div>
<div class="link-card-v2-content">GitHub Copilot CLIのhooksであるsessionStart・sessionEnd・agentStopの違いと発火タイミング、設定方法やユースケースを解説するレポートである。</div>
<img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/report-colot.webp" />
<a data-href="📰GitHub Copilot CLIにおけるagentStop、sessionEnd、sessionStartの違い" class="internal-link"></a>
</div>
%%[[📰GitHub Copilot CLIにおけるagentStop、sessionEnd、sessionStartの違い]]%%
実際に[[GitHub Copilot CLI]]の[[フック (GitHub Copilot)|フック]]の挙動を確かめてまとめてみることにした。
### 環境
| 対象 | バージョン |
| ---------------------- | ---------- |
| [[GitHub Copilot CLI]] | 1.0.11 |
## プロジェクト作成
`.github/hooks/hooks.json`
```json
{
"version": 1,
"hooks": {
"sessionStart": [
{
"type": "command",
"bash": "echo '✨ sessionStart'",
"timeoutSec": 10
}
],
"userPromptSubmitted": [
{
"type": "command",
"bash": "echo '👇 userPromptSubmitted'",
"timeoutSec": 10
}
],
"preToolUse": [
{
"type": "command",
"bash": "echo '🫷preToolUse'",
"timeoutSec": 10
}
],
"postToolUse": [
{
"type": "command",
"bash": "echo '🫸 postToolUse'",
"timeoutSec": 10
}
],
"agentStop": [
{
"type": "command",
"bash": "echo '⛔ agentStop'",
"timeoutSec": 5
}
],
"sessionEnd": [
{
"type": "command",
"bash": "echo '✋ sessionEnd'",
"timeoutSec": 60
}
]
}
}
```
## プロンプト
```
GitHub Copilot CLIでformatやlintをかけるならhooksの何を使うとよい?
```
## 結論
[[sessionStart (GitHub Copilot)|sessionStart]]と[[sessionEnd (GitHub Copilot)|sessionEnd]]のタイミング以外は大体ドキュメント通り。
```mermaid
sequenceDiagram
participant User as ユーザー
participant CLI as Copilot CLI
participant Hook as Hook
participant Agent as エージェント(LLM)
participant Tool as ツール
Note over CLI: CLI起動・初期化
CLI->>CLI: プラグインからHook読み込み
CLI->>CLI: セッション登録 (session.foreground)
CLI->>CLI: MCP/ツール初期化
rect rgb(230, 245, 255)
Note over User,Tool: ターン (ユーザーの入力ごとに繰り返し)
User->>CLI: プロンプト入力
CLI->>Hook: 👇 userPromptSubmitted
CLI->>Hook: ✨ sessionStart
CLI->>Agent: プロンプト送信
loop エージェントがツールを使う間
Agent->>CLI: ツール呼び出し要求
CLI->>Hook: 🫷 preToolUse
CLI->>Tool: ツール実行
Tool-->>CLI: 実行結果
CLI->>Hook: 🫸 postToolUse
CLI-->>Agent: ツール結果返却
end
Agent-->>CLI: 最終応答
CLI->>Hook: ⛔ agentStop
CLI->>Hook: ✋ sessionEnd
CLI-->>User: 応答表示
end
```
| 順序 | イベント | タイミング |
| --- | ----------------------------------------------- | ------------------- |
| 1 | `userPromptSubmitted` | ユーザーがプロンプトを送信した直後 |
| 2 | [[sessionStart (GitHub Copilot)\|sessionStart]] | エージェントセッション開始時 |
| 3 | `preToolUse` | 各ツール実行の直前(ツールごとに発火) |
| 4 | `postToolUse` | 各ツール実行の直後(ツールごとに発火) |
| 5 | [[agentStop (GitHub Copilot)\|agentStop]] | エージェントの応答完了時 |
| 6 | [[sessionEnd (GitHub Copilot)\|sessionEnd]] | セッション終了時 |
ドキュメント・レポートとの差異として **sessionStartとsessionEndは毎プロンプトで呼ばれる** という点がある。少なくとも[[📰GitHub Copilot CLIにおけるagentStop、sessionEnd、sessionStartの違い#フックシステムの全体像]]のシーケンスとは一致していない。
『セッション』とは何者なのか? issueは上がっているが、これが仕様なのかは謎。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" />
<span class="link-card-v2-site-name">Minerva</span>
</div>
<div class="link-card-v2-title">
📝GitHub Copilot CLIのsessionStartとsessionEndのフックが毎プロンプト呼ばれる
</div>
<div class="link-card-v2-content">GitHub Copilot CLI 1.0.11のインタラクティブモードで、sessionStartとsessionEndのフックがセッション単位ではなくプロンプト実行ごとに呼ばれた事象である。バグの可能性があるが仕様か不明で、現時点で解決方法は存在しない状況になった。</div>
<img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/troubleshooting.webp" />
<a data-href="📝GitHub Copilot CLIのsessionStartとsessionEndのフックが毎プロンプト呼ばれる" class="internal-link"></a>
</div>
%%[[📝GitHub Copilot CLIのsessionStartとsessionEndのフックが毎プロンプト呼ばれる]]%%
SDKのドキュメントなども含めると、『セッション』とは『各ターンごとのセッション』であるという見解が有力そう。上記issueも放置されているし。
<div class="link-card-v2">
<div class="link-card-v2-site">
<img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" />
<span class="link-card-v2-site-name">Minerva</span>
</div>
<div class="link-card-v2-title">
📜GitHub Copilot CLIのhookライフサイクル調査
</div>
<div class="link-card-v2-content">GitHub Copilot CLIのデバッグログを解析し、userPromptSubmittedからsessionEndまでのhookイベント発火順序を特定した。mermaidシーケンス図を作成し、CLIセッションとエージェントセッションの二重の「セッション」概念を整理した。sessionStart/sessionEndがインタラクティブモードでプロンプトごとに発火する挙動と、バグ報告copilot-cli#991の事実を確認した。</div>
<img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/claudine-task.webp" />
<a data-href="📜GitHub Copilot CLIのhookライフサイクル調査" class="internal-link"></a>
</div>
%%[[📜GitHub Copilot CLIのhookライフサイクル調査]]%%