All integrations

GitHub Copilot CLI

Copilot CLI in your repo - agent activity on the lock screen.

LiveEditorchirp login
copilot (working) Live Activity preview
what shows on your phone

GitHub Copilot CLI (`gh copilot`) supports a repo-scoped hooks system at `.github/hooks/hooks.json`. The hooks fire on session lifecycle events: `sessionStart`, `preToolUse`, `postToolUse`, `errorOccurred`, `sessionEnd`. Chirp ships a single Python script that handles all five via argv dispatch - same shape as the Claude Code and Kiro hooks.

Unlike Claude Code (where hooks live in `~/.claude/settings.json`, global to the user), Copilot's hooks live in the repo. This is intentional - Copilot CLI is GitHub's pitch as the "agent that lives in your repo," so the hooks are repo-scoped too. Multiple developers on the same repo all get Chirp activities without per-laptop setup, as long as each ran `chirp login`.

Prerequisites

  • GitHub Copilot CLI installed (`gh extension install github/gh-copilot`).
  • Python 3 on PATH.
  • `chirp login` run once per developer machine.

Setup

  1. 1

    Drop the hook script into .github/hooks/

    Single Python file. argv[1] is the event name (Copilot CLI passes it on the command line as configured in hooks.json). The script reads the event JSON from stdin and posts to Chirp's normalizer for the @copilot-cli activity.

    .github/hooks/chirp-hook.py
    #!/usr/bin/env python3
    """GitHub Copilot CLI → Chirp."""
    import sys, os, urllib.request
    
    def main():
        event = sys.argv[1] if len(sys.argv) > 1 else "unknown"
        payload = sys.stdin.read()
        creds_path = os.path.expanduser("~/.chirp/credentials")
        if not os.path.exists(creds_path):
            return  # not paired; silently skip
        token = open(creds_path).read().strip()
    
        req = urllib.request.Request(
            f"https://api.chirpapp.dev/v1/webhooks/copilot-cli?event={event}",
            data=payload.encode(),
            headers={
                "Authorization": f"Bearer {token}",
                "Content-Type": "application/json",
            },
        )
        try:
            urllib.request.urlopen(req, timeout=2)
        except Exception:
            pass
    
    if __name__ == "__main__":
        main()
  2. 2

    Commit the hooks.json manifest

    Maps each Copilot CLI lifecycle event to the script + the event name. version: 1 is required (Copilot rejects unversioned hook configs).

    .github/hooks/hooks.json
    {
      "version": 1,
      "hooks": {
        "sessionStart":  [{ "command": "python3 .github/hooks/chirp-hook.py sessionStart" }],
        "preToolUse":    [{ "command": "python3 .github/hooks/chirp-hook.py preToolUse" }],
        "postToolUse":   [{ "command": "python3 .github/hooks/chirp-hook.py postToolUse" }],
        "errorOccurred": [{ "command": "python3 .github/hooks/chirp-hook.py errorOccurred" }],
        "sessionEnd":    [{ "command": "python3 .github/hooks/chirp-hook.py sessionEnd" }]
      }
    }
  3. 3

    Pair each developer's CLI

    Every dev on the repo runs chirp login once on their laptop. The hooks read ~/.chirp/credentials; without it, the script silently no-ops (so a teammate without Chirp doesn't get errors).

    shell
    chirp login
  4. 4

    Run gh copilot in the repo

    From the repo root: gh copilot suggest or gh copilot explain. Copilot auto-discovers .github/hooks/hooks.json and fires the configured hooks on each lifecycle event.

    shell
    gh copilot suggest "how do I revert the last commit"

What you’ll see

Card header: GitHub Copilot mark + "Copilot CLI · WORKING" + repo path. Action line shows the current tool call (`bash · git log -5`, `read · src/auth.ts`). errorOccurred surfaces as a red badge on the timeline (with the error message) without ending the card; sessionEnd closes it green or red based on the final state. Multiple parallel `gh copilot` invocations in the same repo coalesce on session ID.

Troubleshooting

Copilot CLI doesn't fire hooks at all.
gh copilot --version - hooks were added in v0.5.4. Older versions silently ignore hooks.json. gh extension upgrade gh-copilot fixes it.
Hook fires but card never appears.
The script silently skips when ~/.chirp/credentials is missing. Run chirp login on the laptop where Copilot is running. To debug, change the script's pass to print('chirp:', e, file=sys.stderr) and re-run.
I want this for one repo only, not all repos.
It already is - Copilot CLI's hooks are per-repo by design. The file lives in .github/hooks/, so only repos you've added it to wire up Chirp.
External docs →