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.