fix: align hooks docs with official GitHub Copilot hooks spec

- Remove non-existent copilotAgentCommit event from all articles
- Add 5 missing hook events: preToolUse, postToolUse, agentStop,
  subagentStop, errorOccurred
- Fix hooks location from .copilot/hooks.json to .github/hooks/*.json
- Add powershell field to config format
- Add preToolUse security gating example (approve/deny tool executions)
- Update glossary and coding agent article cross-references

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Aaron Powell
2026-02-26 14:01:17 +11:00
parent a88c9f89d5
commit 31c41a6a1c
3 changed files with 83 additions and 46 deletions

View File

@@ -16,19 +16,20 @@ prerequisites:
- Basic understanding of GitHub Copilot agents
---
Hooks let you run automated scripts at key moments during a Copilot agent sessionwhen a session starts, when the user submits a prompt, or when the agent is about to commit code. They're the glue between Copilot's AI capabilities and your team's existing tooling: linters, formatters, governance scanners, and notification systems.
Hooks let you run automated scripts at key moments during a Copilot agent sessionwhen a session starts or ends, when the user submits a prompt, or before and after the agent uses a tool. They're the glue between Copilot's AI capabilities and your team's existing tooling: linters, formatters, governance scanners, and notification systems.
This article explains how hooks work, how to configure them, and practical patterns for common automation needs.
## What Are Hooks?
Hooks are shell commands or scripts that run automatically in response to lifecycle events during a Copilot agent session. They execute outside the AI modelthey're deterministic, repeatable, and under your full control.
Hooks are shell commands or scripts that run automatically in response to lifecycle events during a Copilot agent session. They execute outside the AI model, they're deterministic, repeatable, and under your full control.
**Key characteristics**:
- Hooks run as shell commands on the user's machine
- They execute synchronously—the agent waits for them to complete
- They can block actions (e.g., prevent commits that fail linting)
- They're defined in a `hooks.json` configuration file
- They're defined in JSON files stored at `.github/hooks/*.json` in your repository
- They receive detailed context via JSON input, enabling context-aware automation
- They can include bundled scripts for complex logic
### When to Use Hooks vs Other Customizations
@@ -57,28 +58,8 @@ hooks/
└── check.sh
```
### README.md
> Note: Not all of these files are required for a generalised hook implementation. In your own repository, hooks are stored as JSON files in `.github/hooks/` (e.g., `.github/hooks/my-hook.json`). The folder structure above with README.md is specific to the Awesome Copilot repository for documentation purposes.
The README provides metadata and documentation:
```markdown
---
name: 'Auto Format'
description: 'Automatically formats code using project formatters before commits'
tags: ['formatting', 'code-quality']
---
# Auto Format
Runs your project's configured formatter (Prettier, Black, gofmt, etc.)
automatically before the agent commits changes.
## Setup
1. Ensure your formatter is installed and configured
2. Copy the hooks.json to your `.copilot/hooks.json`
3. Adjust the formatter command for your project
```
### hooks.json
@@ -88,7 +69,7 @@ The configuration defines which events trigger which commands:
{
"version": 1,
"hooks": {
"copilotAgentCommit": [
"postToolUse": [
{
"type": "command",
"bash": "npx prettier --write .",
@@ -106,10 +87,16 @@ Hooks can trigger on several lifecycle events:
| Event | When It Fires | Common Use Cases |
|-------|---------------|------------------|
| `sessionStart` | Agent session begins | Initialize logging, check prerequisites |
| `sessionEnd` | Agent session ends | Clean up temp files, send notifications |
| `userPromptSubmitted` | User sends a message | Scan for sensitive data, log for governance |
| `copilotAgentCommit` | Agent is about to commit | Format code, run linters, validate changes |
| `sessionStart` | Agent session begins or resumes | Initialize environments, log session starts, validate project state |
| `sessionEnd` | Agent session completes or is terminated | Clean up temp files, generate reports, send notifications |
| `userPromptSubmitted` | User submits a prompt | Log requests for auditing and compliance |
| `preToolUse` | Before the agent uses any tool (e.g., `bash`, `edit`) | **Approve or deny** tool executions, block dangerous commands, enforce security policies |
| `postToolUse` | After a tool completes execution | Log results, track usage, format code after edits, send failure alerts |
| `agentStop` | Main agent finishes responding to a prompt | Run final linters/formatters, validate complete changes |
| `subagentStop` | A subagent completes before returning results | Audit subagent outputs, log subagent activity |
| `errorOccurred` | An error occurs during agent execution | Log errors for debugging, send notifications, track error patterns |
> **Key insight**: The `preToolUse` hook is the most powerful — it can **approve or deny** individual tool executions. This enables fine-grained security policies like blocking specific shell commands or requiring approval for sensitive file operations.
### Event Configuration
@@ -119,6 +106,7 @@ Each hook entry supports these fields:
{
"type": "command",
"bash": "./scripts/my-check.sh",
"powershell": "./scripts/my-check.ps1",
"cwd": ".",
"timeoutSec": 10,
"env": {
@@ -129,25 +117,50 @@ Each hook entry supports these fields:
**type**: Always `"command"` for shell-based hooks.
**bash**: The command or script to execute. Can be inline or reference a script file.
**bash**: The command or script to execute on Unix systems. Can be inline or reference a script file.
**cwd**: Working directory for the command. Use `"."` for the repository root.
**powershell**: The command or script to execute on Windows systems. Either `bash` or `powershell` (or both) must be provided.
**timeoutSec**: Maximum execution time. The hook is killed if it exceeds this limit.
**cwd**: Working directory for the command (relative to repository root).
**env**: Additional environment variables passed to the command.
**timeoutSec**: Maximum execution time in seconds (default: 30). The hook is killed if it exceeds this limit.
**env**: Additional environment variables merged with the existing environment.
### README.md
The README provides metadata and documentation for the Awesome Copilot repository. While not required in your own implementation, it serves as a useful way to document them for your team.
```markdown
---
name: 'Auto Format'
description: 'Automatically formats code using project formatters before commits'
tags: ['formatting', 'code-quality']
---
# Auto Format
Runs your project's configured formatter (Prettier, Black, gofmt, etc.)
automatically before the agent commits changes.
## Setup
1. Ensure your formatter is installed and configured
2. Copy the hooks.json to your `.github/hooks/` directory
3. Adjust the formatter command for your project
```
## Practical Examples
### Auto-Format Before Commit
### Auto-Format After Edits
Ensure all code is formatted before the agent commits:
Ensure all code is formatted after the agent edits files:
```json
{
"version": 1,
"hooks": {
"copilotAgentCommit": [
"postToolUse": [
{
"type": "command",
"bash": "npx prettier --write . && git add -A",
@@ -159,15 +172,15 @@ Ensure all code is formatted before the agent commits:
}
```
### Lint Check Before Commit
### Lint Check When Agent Completes
Run ESLint and block the commit if there are errors:
Run ESLint after the agent finishes responding and block if there are errors:
```json
{
"version": 1,
"hooks": {
"copilotAgentCommit": [
"agentStop": [
{
"type": "command",
"bash": "npx eslint . --max-warnings 0",
@@ -179,7 +192,29 @@ Run ESLint and block the commit if there are errors:
}
```
If the lint command exits with a non-zero status, the commit is blocked.
If the lint command exits with a non-zero status, the action is blocked.
### Security Gating with preToolUse
Block dangerous commands before they execute:
```json
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "./scripts/security-check.sh",
"cwd": ".",
"timeoutSec": 15
}
]
}
}
```
The `preToolUse` hook receives JSON input with details about the tool being called. Your script can inspect this input and exit with a non-zero code to **deny** the tool execution, or exit with zero to **approve** it.
### Governance Audit
@@ -290,13 +325,13 @@ echo "Pre-commit checks passed ✅"
## Common Questions
**Q: Where do I put hooks.json?**
**Q: Where do I put hooks configuration files?**
A: Place it at `.copilot/hooks.json` in your repository root. This makes hooks available to all team members.
A: Place them in the `.github/hooks/` directory in your repository (e.g., `.github/hooks/my-hook.json`). You can have multiple hook files — all are loaded automatically. This makes hooks available to all team members.
**Q: Can hooks access the user's prompt text?**
A: Yes, for `userPromptSubmitted` events the prompt content is available to the hook script via environment variables. See the [GitHub Copilot hooks documentation](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/use-hooks) for details.
A: Yes, for `userPromptSubmitted` events the prompt content is available via JSON input to the hook script. Other hooks like `preToolUse` and `postToolUse` receive context about the tool being called. See the [GitHub Copilot hooks documentation](https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-hooks) for details.
**Q: What happens if a hook times out?**

View File

@@ -185,9 +185,9 @@ A standardized protocol for connecting AI assistants like GitHub Copilot to exte
### Hook
A shell command or script that runs automatically in response to lifecycle events during a Copilot agent session. Hooks are defined in a `hooks.json` file and can trigger on events like session start, prompt submission, or before a commit. They provide deterministic automation—linting, formatting, governance scanning—that doesn't depend on the AI remembering to do it.
A shell command or script that runs automatically in response to lifecycle events during a Copilot agent session. Hooks are stored as JSON files in `.github/hooks/` and can trigger on events like session start/end, prompt submission, before/after tool use, and when errors occur. They provide deterministic automation—linting, formatting, governance scanning—that doesn't depend on the AI remembering to do it.
**Example**: A `copilotAgentCommit` hook that runs Prettier before every commit the agent makes.
**Example**: A `postToolUse` hook that runs Prettier after the agent edits files, or a `preToolUse` hook that blocks dangerous shell commands.
**When to use**: For deterministic automation that must happen reliably, like formatting code, running linters, or auditing prompts for compliance.

View File

@@ -208,7 +208,9 @@ The agent will read your feedback, make changes, and push new commits to the sam
Hooks are especially valuable with the coding agent because they provide deterministic guardrails for autonomous work:
- **`copilotAgentCommit`**: Format code, run linters, and validate changes before every commit the agent makes
- **`preToolUse`**: Approve or deny tool executions — block dangerous commands and enforce security policies
- **`postToolUse`**: Format code, run linters, and validate changes after edits
- **`agentStop`**: Run final checks (e.g., full lint pass) when the agent finishes responding
- **`sessionStart`**: Log the start of autonomous sessions for governance
- **`sessionEnd`**: Send notifications when the agent finishes