GitHub Copilot CLI
Install BirdyBeep's Copilot CLI hooks to receive notifications when a turn finishes or fails. Copilot loads the hooks immediately.
- ~2 min setup
- no restart
- open source
Quick install
If this machine is already paired, one command configures Copilot CLI:
birdybeep agent install copilot Ready after installation
Copilot loads the hook file as soon as it is written. The app shows the integration as
installed, and the next Copilot session appears after its first event.
What gets written
Install writes a single dedicated file, ~/.copilot/hooks/birdybeep.json — or the same
path under $COPILOT_HOME if you've set it. Copilot reads every JSON file in that directory,
so BirdyBeep never opens or rewrites your other hook files. The file is written with 0600 permissions, and re-running install changes nothing:
{
"version": 1,
"hooks": {
"sessionStart": [
{
"type": "command",
"bash": "birdybeep hook copilot sessionStart",
"powershell": "birdybeep hook copilot sessionStart",
"timeoutSec": 10
}
],
"agentStop": [
{
"type": "command",
"bash": "birdybeep hook copilot agentStop",
"powershell": "birdybeep hook copilot agentStop",
"timeoutSec": 10
}
]
}
}
The same entry is registered under all eight Copilot hook events — sessionStart,
userPromptSubmitted, preToolUse, postToolUse,
agentStop, subagentStop, errorOccurred and
sessionEnd — with matching bash and powershell commands.
Each command ends in the event name. Copilot's payload doesn't say which event fired, so the adapter needs it on the command line to map the event correctly.
Copilot passes each event to the command as JSON on stdin. The command reads your machine token from the secure store at event time and does not write it here.
A slow or offline backend never holds up Copilot: the send itself has a hard ~3s timeout, and
anything that doesn't make it goes to the local 24h queue to be retried on a later event. The
timeoutSec: 10 in the hook entry is Copilot's own kill deadline — a backstop, not the
thing that keeps the hook fast.
Events you'll get
| copilot hook | beep type | example push |
|---|---|---|
| sessionStart | session_started | silent — the session appears in the app |
| userPromptSubmitted | session_active | silent — marks the session running |
| agentStop | agent_completed | copilot finished |
| errorOccurred | agent_failed | copilot hit an error |
| sessionEnd | session_ended | silent — settles the session (failed on error · timeout) |
| preToolUse · postToolUse | tool_* | silent — tracked in the session |
| subagentStop | subagent_completed | silent — tracked in the session |
With Private Mode on (free for everyone), the push drops repo, branch, path, and command.
Test it
Send a real test beep to confirm the integration end to end:
birdybeep test
# → beep sent. check your phone.
If the test beep does not arrive, run birdybeep doctor. It checks pairing, the
hooks file, and delivery.
Security note
security note
Copilot hook payloads include prompts, tool arguments and results, transcripts, subagent
responses, and error messages. BirdyBeep removes those fields before sending the event. It
sends only the tool name and status and hashes the working directory. BirdyBeep reads the
machine token from your OS keychain or from ~/.config/birdybeep/ with restricted
permissions and does not write it to repositories or coding-agent configuration files. You can
revoke or rotate the token in the app. BirdyBeep does not store notification bodies. The adapter
source is MIT-licensed on
GitHub.