{"meta":{"title":"Using hooks with GitHub Copilot CLI","intro":"Extend GitHub Copilot agent behavior with custom shell commands at key points during agent execution.","product":"GitHub Copilot","breadcrumbs":[{"href":"/en/copilot","title":"GitHub Copilot"},{"href":"/en/copilot/how-tos","title":"How-tos"},{"href":"/en/copilot/how-tos/copilot-cli","title":"Copilot CLI"},{"href":"/en/copilot/how-tos/copilot-cli/customize-copilot","title":"Customize Copilot CLI"},{"href":"/en/copilot/how-tos/copilot-cli/customize-copilot/use-hooks","title":"Use hooks"}],"documentType":"article"},"body":"# Using hooks with GitHub Copilot CLI\n\nExtend GitHub Copilot agent behavior with custom shell commands at key points during agent execution.\n\nHooks allow you to extend and customize the behavior of GitHub Copilot agents by executing custom shell commands at key points during agent execution. For a conceptual overview of hooks—including details of the available hook triggers—see [About hooks for GitHub Copilot](/en/copilot/concepts/agents/hooks).\n\n## Prerequisite\n\n**Windows users only:** The example hooks in this article are designed to run on Windows, Linux, and macOS. For Windows, they use PowerShell and require you to have PowerShell 7.0 or later installed and in your PATH. You can check your PowerShell version by running `pwsh --version` in a terminal. To install PowerShell, run `winget install Microsoft.PowerShell` then restart your terminal.\n\n## Creating a repository-level hook\n\n1. Create a new `NAME.json` file (where `NAME` describes the purpose of the file) in the `.github/hooks/` folder of your repository.\n\n2. In your text editor, copy and paste the following hook template. Remove any hooks you don't plan on using from the `hooks` array.\n\n   ```json copy\n   {\n     \"version\": 1,\n     \"hooks\": {\n       \"sessionStart\": [...],\n       \"sessionEnd\": [...],\n       \"userPromptSubmitted\": [...],\n       \"preToolUse\": [...],\n       \"postToolUse\": [...],\n       \"errorOccurred\": [...]\n     }\n   }\n   ```\n\n3. Configure your hook syntax under the `bash` and `powershell` keys, or directly reference script files you have created.\n\n   > \\[!NOTE]\n   > Include both a `bash` key (with a script for Linux and macOS) and a `powershell` key (for a script for Windows) to allow the hooks to run on all three operating systems. Copilot uses the appropriate key based on the user's operating system.\n\n   * This example runs a script that outputs the start date of the session to a log file using the `sessionStart` hook:\n\n     ```json copy\n     \"sessionStart\": [\n       {\n         \"type\": \"command\",\n         \"bash\": \"echo \\\"Session started: $(date)\\\" >> logs/session.log\",\n         \"powershell\": \"Add-Content -Path logs/session.log -Value \\\"Session started: $(Get-Date)\\\"\",\n         \"cwd\": \".\",\n         \"timeoutSec\": 10\n       }\n     ],\n     ```\n\n   * This example calls out to an external `log-prompt` script:\n\n     ```json copy\n     \"userPromptSubmitted\": [\n       {\n         \"type\": \"command\",\n         \"bash\": \"./scripts/log-prompt.sh\",\n         \"powershell\": \"./scripts/log-prompt.ps1\",\n         \"cwd\": \"scripts\",\n         \"env\": {\n           \"LOG_LEVEL\": \"INFO\"\n         }\n       }\n     ],\n     ```\n\n     For a full reference on the input JSON from agent sessions along with sample scripts, see [GitHub Copilot hooks reference](/en/copilot/reference/hooks-reference).\n\n4. Commit the file to the repository and merge it into the default branch. Your hooks will now run during agent sessions.\n\n## Creating a user-level hook\n\nUser-level hooks are configured just like repository-level hooks, but the hook files are stored locally, below your home directory.\n\nThe following examples for macOS and Windows show how to configure hooks that will play a sound and display a message box when the CLI finishes responding to a prompt, and when you quit Copilot CLI. Hooks for Linux would be similar to the macOS example, but would use Linux tools for playing sounds and displaying messages.\n\n### User-level example for macOS\n\n1. Create a file called `notification-hooks.json` in `~/.copilot/hooks/`.\n\n   > \\[!NOTE]\n   > If `COPILOT_HOME` is set, create the file in `$COPILOT_HOME/hooks/`.\n\n2. Copy and paste the following JSON into the file:\n\n   ```json copy\n   {\n     \"version\": 1,\n     \"hooks\": {\n       \"agentStop\": [\n         {\n           \"type\": \"command\",\n           \"bash\": \"osascript -e 'do shell script \\\"afplay /System/Library/Sounds/Funk.aiff &> /dev/null &\\\"' -e 'display dialog \\\"Agent stopped.\\\" with title \\\"Hook-generated message\\\" buttons {\\\"OK\\\"} default button \\\"OK\\\"'\",\n           \"timeoutSec\": 5\n         }\n       ],\n       \"sessionEnd\": [\n         {\n           \"type\": \"command\",\n           \"bash\": \"osascript -e 'do shell script \\\"afplay /System/Library/Sounds/Funk.aiff &> /dev/null &\\\"' -e 'display dialog \\\"Session ended.\\\" with title \\\"Hook-generated message\\\" buttons {\\\"OK\\\"} default button \\\"OK\\\"'\",\n           \"timeoutSec\": 5\n         }\n       ]\n     }\n   }\n   ```\n\n3. Start, or restart, Copilot CLI.\n\n   > \\[!NOTE]\n   > Changes to hook configurations are loaded when the CLI starts.\n\n4. Enter a prompt and check that you hear a sound and see a message box when the agent finishes responding, and when you quit the CLI.\n\n5. Delete the `notification-hooks.json` file to remove these hooks.\n\n### User-level example for Windows\n\n1. Create a file called `notification-hooks.json` in `%USERPROFILE%\\.copilot\\hooks\\`.\n\n   > \\[!NOTE]\n   > If `COPILOT_HOME` is set, create the file in `%COPILOT_HOME%\\hooks\\`.\n\n2. Copy and paste the following JSON into the file:\n\n   ```json copy\n   {\n     \"version\": 1,\n     \"hooks\": {\n       \"agentStop\": [\n         {\n           \"type\": \"command\",\n           \"powershell\": \"Add-Type -AssemblyName System.Windows.Forms; [System.Media.SystemSounds]::Asterisk.Play(); [System.Windows.Forms.MessageBox]::Show('Agent stopped.', 'Hook-generated message') | Out-Null\",\n           \"timeoutSec\": 5\n         }\n       ],\n       \"sessionEnd\": [\n         {\n           \"type\": \"command\",\n           \"powershell\": \"Add-Type -AssemblyName System.Windows.Forms; [System.Media.SystemSounds]::Asterisk.Play(); [System.Windows.Forms.MessageBox]::Show('Session ended.', 'Hook-generated message') | Out-Null\",\n           \"timeoutSec\": 5\n         }\n       ]\n     }\n   }\n   ```\n\n3. Start, or restart, Copilot CLI.\n\n   > \\[!NOTE]\n   > Changes to hook configurations are loaded when the CLI starts.\n\n4. Enter a prompt and check that you hear a sound and see a message box when the agent finishes responding, and when you quit the CLI.\n\n5. Delete the `notification-hooks.json` file to remove these hooks.\n\n## Troubleshooting\n\nIf you run into problems using hooks, use the following table to troubleshoot.\n\n| Issue                   | Action                                                                                                                                                                                                                                                                                                                                                                                                |\n| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Hooks are not executing | <ul><li>Verify the JSON file is in the `.github/hooks/` directory.</li><li>Check for valid JSON syntax (for example, `jq .  hooks.json`).</li><li>Ensure `version: 1` is specified in your `hooks.json` file.</li><li>Verify the script you are calling from your hook is executable (`chmod +x script.sh`)</li><li>Check that the script has a proper shebang (for example, `#!/bin/bash`)</li></ul> |\n| Hooks are timing out    | <ul><li>The default timeout is 30 seconds. Increase `timeoutSec` in the configuration if needed.</li><li>Optimize script performance by avoiding unnecessary operations.</li></ul>                                                                                                                                                                                                                    |\n| Invalid JSON output     | <ul><li>Ensure the output is on a single line.</li><li>On Unix, use `jq -c` to compact and validate the JSON output.</li><li>On Windows, use the `ConvertTo-Json -Compress` command in PowerShell to do the same.</li></ul>                                                                                                                                                                           |\n\n## Debugging\n\nYou can debug hooks using the following methods:\n\n* **Enable verbose logging** in the script to inspect the input data and trace script execution.\n\n  ```shell copy\n  #!/bin/bash\n  set -x  # Enable bash debug mode\n  INPUT=$(cat)\n  echo \"DEBUG: Received input\" >&2\n  echo \"$INPUT\" >&2\n  # ... rest of script\n  ```\n\n* **Test hooks locally** by piping test input into your hook to validate its behavior:\n\n  ```shell copy\n  # Create test input\n  echo '{\"timestamp\":1704614400000,\"cwd\":\"/tmp\",\"toolName\":\"bash\",\"toolArgs\":\"{\\\"command\\\":\\\"ls\\\"}\"}' | ./my-hook.sh\n\n  # Check exit code\n  echo $?\n\n  # Validate output is valid JSON\n  ./my-hook.sh | jq .\n  ```\n\n## Further reading\n\n* [GitHub Copilot hooks reference](/en/copilot/reference/hooks-reference)\n* [About GitHub Copilot cloud agent](/en/copilot/concepts/agents/cloud-agent/about-cloud-agent)\n* [About GitHub Copilot CLI](/en/copilot/concepts/agents/copilot-cli/about-copilot-cli)\n* [Configure the development environment](/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/customize-the-agent-environment)"}