Skip to content

Gemini CLIのHooksを使う

Claude Codeと同じような機能がGemini CLIにもある。

設定はプロジェクトの .gemini/settings.json または ~/.gemini/settings.json 等で以下のように書く。

{
"hooks": {
"BeforeTool": [
{
"matcher": "write_file|replace",
"hooks": [
{
"name": "security-check",
"type": "command",
"command": "$GEMINI_PROJECT_DIR/.gemini/hooks/security.sh",
"timeout": 5000
}
]
}
]
}
}
  • matcher … ツールの名前に正規表現でマッチする、* なら全てにマッチする
  • command … どのプログラムを使うか指定する(書き方は後述)
  • timeout … ミリ秒で指定

command で指定するツールは、ツールを禁止する場合であっても、基本的にはJSONを標準出力へ書き出し、終了コード 0 で終わらせておくといい。

{
"decision": "allow"
}

禁止の場合は decision と、その理由も書いておく。

{
"decision": "deny",
"reason": "エラーです"
}

コマンド自体がエラーを起こした場合は終了コード 2 でプログラムを終わらせるといい。これ以外の終了コードでは、警告はされるけれど止めることができない。また、Geminiは標準エラー出力をそのまま原因として使うので、ここで書き出しておくとユーザーが原因を調べられる。

Hooksではイベント(BeforeTool など)ごとに、共通している部分もあるが、書き出せるJSONのパラメータが異なる。例えば BeforeTool の場合は、decision, reason を理解することが以下の資料から読める。hookSpecificOutput.tool_input もあるが、これはネストされたオブジェクトを意味するのだろう。