Copilot's coding agent supports preToolUse hooks, configured in .github/hooks/hooks.json on your default branch. youtube
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": ".github/hooks/omni-intercept.sh",
"timeoutSec": 10
}
]
}
}Create .github/hooks/omni-intercept.sh:
#!/usr/bin/env bash
set -euo pipefail
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.toolName // ""')
COMMAND=$(echo "$INPUT" | jq -r '.toolArgs' | jq -r '.command // ""')
# Only inspect shell/bash tool calls
if [ "$TOOL_NAME" != "bash" ] && [ "$TOOL_NAME" != "shell" ]; then
exit 0
fi
# Intercept git commit → omni commit
if echo "$COMMAND" | grep -qE '^git\s+commit'; then
echo "Use 'omni commit --yes --json' instead of git commit." >&2
exit 2
fi
# Intercept gh pr create → omni pr
if echo "$COMMAND" | grep -qE '(gh\s+pr\s+create|git\s+push)'; then
echo "Use 'omni pr --yes --json' instead of gh pr create / git push." >&2
exit 2
fi
# Allow everything else
exit 0Then make it executable:
chmod +x .github/hooks/omni-intercept.shHow it works:
- The
preToolUsehook fires before the agent executes any tool. youtube - The stdin JSON contains
toolName(e.g."bash") andtoolArgsas a JSON string that needs a second parse to extract.command. youtube - Exit code 0 allows the command; exit code 2 blocks it and feeds
stderrback to the agent as feedback. youtube - Note: Copilot's coding agent already cannot run
git pushdirectly — it's restricted to pushing only tocopilot/branches through an internal mechanism. The main command to intercept isgit commit. developers.openai
(Optional) Add custom instructions for reinforcement:
Create .github/copilot-instructions.md:
## Git Policy
- Never run `git commit` or `gh pr create` directly.
- Use `omni commit --yes --json` for commits.
- Use `omni pr --yes --json` for pull requests.This gives you the same two-layer setup as Claude Code: custom instructions guide the agent, the preToolUse hook enforces it. developers.openai