Skip to content

Receives GitHub webhook events and routes @mention comments to the agent fleet. Agent replies are posted back as GitHub comments.

How It Works ​

@protoquinn comment on issue/PR
  → GitHub sends POST /webhook/github
    → GitHubPlugin validates HMAC-SHA256 signature
      → Publishes message.inbound.github.{owner}.{repo}.{event}.{number}
        → RouterPlugin routes to Quinn (skillHint: bug_triage / pr_review)
          → Quinn processes and responds
            → RouterPlugin publishes message.outbound.github.{owner}.{repo}.{number}
              → GitHubPlugin posts reply as GitHub comment

Setup ​

1. Environment Variables ​

VariableRequiredDescription
GITHUB_TOKENYes*PAT used to post comment replies (enables the plugin)
GITHUB_APP_IDNoGitHub App ID — preferred over the PAT for write operations (comments, PR ops, issue closure) so they author as @protoquinn[bot]
GITHUB_APP_PRIVATE_KEYNoGitHub App PEM private key (newlines as \n). Must be set together with GITHUB_APP_ID
GITHUB_WEBHOOK_SECRETRecommendedValidates X-Hub-Signature-256 on inbound payloads
GITHUB_WEBHOOK_PORTNoPort for the webhook HTTP server (default: 8082)

The plugin is automatically skipped if GITHUB_TOKEN is not set.

* Write operations resolve auth via the shared makeGitHubAuth (lib/github-auth.ts): the Quinn GitHub App when both GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY are set, otherwise the GITHUB_TOKEN PAT. Setting exactly one of the App pair is a misconfiguration and fails loud rather than silently writing as the operator's PAT identity.

2. github.yaml ​

Place a github.yaml in your workspace directory (default: workspace/github.yaml). If absent, the plugin loads with built-in defaults.

yaml
# Handle to watch for in comments. Case-insensitive match.
mentionHandle: "@protoquinn"

# Skill routed to per GitHub event type.
# Becomes the skillHint on the bus message — tells RouterPlugin which agent to call.
skillHints:
  issue_comment: bug_triage              # @mention in a comment on an issue
  issues: bug_triage                     # @mention in the body of a new issue
  pull_request_review_comment: pr_review # @mention in a PR review comment
  pull_request: pr_review                # @mention in a PR description

3. Register the Webhook in GitHub ​

In your repo: Settings → Webhooks → Add webhook

FieldValue
Payload URLhttps://hooks.proto-labs.ai/webhook/github
Content typeapplication/json
SecretValue of GITHUB_WEBHOOK_SECRET
SSL verificationEnable
EventsIssue comments, Issues, Pull request review comments, Pull requests

4. GitHub Token Permissions ​

Fine-grained PAT scoped to the target repo:

PermissionLevel
IssuesRead & Write
Pull requestsRead & Write
ActionsRead
ContentsRead

Issues Write covers comment replies and issue state changes. The same permissions apply to the Quinn GitHub App installation when used instead of a PAT.

Bus Topics ​

TopicDirectionDescription
message.inbound.github.{owner}.{repo}.{event}.{number}Inbound@mention received
message.outbound.github.{owner}.{repo}.{number}OutboundReply to post as comment
github.issue.openedInbound (additive)Every issue opened/reopened — additive signal for any subscriber

Inbound Payload ​

typescript
{
  sender: string;       // GitHub username of the commenter
  channel: string;      // "{owner}/{repo}#{number}" — stable context key for A2A
  content: string;      // Full context string: event header + title + author + URL + body
  skillHint?: string;   // From github.yaml skillHints (e.g. "bug_triage", "pr_review")
  github: {
    event: string;      // GitHub event type (issue_comment, pull_request, etc.)
    owner: string;
    repo: string;
    number: number;     // Issue or PR number
    title: string;
    url: string;        // Direct URL to the comment
  };
}

Outbound Payload ​

typescript
{
  content: string;  // Text to post as a GitHub comment
}

Match correlationId from the inbound message — the plugin uses it to look up the pending comment context (owner, repo, number).

Supported Events ​

GitHub EventTriggerDefault Skill
issue_commentComment containing @mention on an issuebug_triage
issuesNew issue body containing @mentionbug_triage
pull_request_review_commentReview comment containing @mentionpr_review
pull_requestPR opened/updated with @mention in bodypr_review
repository (created)New repository created in the orgmessage.inbound.onboard

Org Webhook: repository.created ​

When a new repository is created in the GitHub org, the plugin publishes message.inbound.onboard so Ava (or any subscriber) can automatically onboard the project.

Onboard Bus Payload ​

typescript
{
  event: "repository.created";
  owner: string;       // org or user name
  repo: string;        // repository name
  fullName: string;    // "owner/repo"
  url: string;         // HTML URL of the repository
  description: string; // repository description (empty string if none)
  isPrivate: boolean;
}

Topic: message.inbound.onboard

Register the Org Webhook ​

Register a single org-level webhook so all new repositories trigger the event automatically — no per-repo webhook needed.

bash
gh api orgs/protoLabsAI/hooks \
  --method POST \
  --field name=web \
  --field "config[url]=https://hooks.proto-labs.ai/webhook/github" \
  --field "config[content_type]=json" \
  --field "config[secret]=$GITHUB_WEBHOOK_SECRET" \
  --field "config[insecure_ssl]=0" \
  --field "events[]=repository"

Signature Validation ​

Requests are validated against X-Hub-Signature-256 using HMAC-SHA256 with GITHUB_WEBHOOK_SECRET. Requests with invalid or missing signatures are rejected with 401.

If GITHUB_WEBHOOK_SECRET is not set, signature validation is skipped (not recommended for production).

Quinn PR Review ​

The GitHub plugin is the entry point for Quinn's PR review pipeline. See Use Quinn PR review for the full review pipeline, vector context system, and configuration.

protoWorkstacean — a switchboard, not an agent.