The GitHub plugin
Most support teams run the same broken loop: members report a bug, staff answer it five separate times, someone eventually files an issue, and nobody ever tells those five members it got fixed. This plugin closes that loop, without giving Onyx access to your code.
What it does
It knows what you already track. Onyx keeps a local copy of your open issues and checks it on every answer. When a member describes something you already have an issue for, Onyx tells them the team is aware and it is being worked on, instead of guessing or opening a duplicate ticket.
It files issues from a conversation. Staff can run /github issue create, or just say "@Onyx open a GitHub issue for this" in a channel or a ticket. Onyx drafts the issue from the conversation and shows it to you. Nothing reaches GitHub until you press the button.
It answers "when is it coming?" If an issue is in a milestone, Onyx knows and can say it is planned for that release. It will never give a member a date: milestone due dates are internal targets that move, and a support bot repeating one turns an estimate into a promise.
It tells the reporters when it ships. Link a ticket to an issue and the member who reported it gets pinged when it is fixed, either the moment the issue closes, or, if you prefer, only once a release actually ships it. The second option needs your release notes to reference issues ("Fixes #482"); GitHub's auto-generated notes link pull requests instead, which Onyx cannot resolve to issues without access it does not ask for.
It keeps them posted in between. Telling someone "we're aware of this" is a promise, and for a real bug the fix can be weeks away. Start any comment on the issue with /public and Onyx posts it to every open ticket waiting on that issue, mentioning the people who reported it:
/public Found it. A bad cache key. Fix goes out this afternoon.
In the meantime a hard refresh works around it.
Comments you don't mark are never relayed. That is deliberate: an issue thread is where your engineers talk to each other, and half of what's in it isn't written for the person who reported the bug. Marking a comment is also what makes you write it for them, which is the difference between forwarding information and actually telling someone something.
It spots patterns. Optionally, once a day Onyx reviews the tickets you closed recently, groups the ones describing the same problem, drops anything you already track, and offers you a drafted issue for what is left.
Onyx never asks to read your code
This is enforced twice, not promised once.
The plugin uses a fine-grained GitHub token that you scope to two permissions:
- Issues: Read and write
- Metadata: Read-only
- Contents: leave at No access
When you save it, Onyx checks the token against each repository you connect. If the token can read the code in a private repository, it is refused and not saved, and the error tells you exactly what to change. Classic tokens are refused outright, because the repo scope always carries code access and cannot be narrowed.
On top of that, there is no code path in the plugin that fetches file contents, trees, commits, or code search. The one call that touches the contents endpoint exists solely to reject a token that succeeds at it.
One honest caveat, because the stronger version of this claim is not true: every fine-grained token GitHub issues carries read-only access to public repositories, and there is no setting that removes it. That is why the check above is about private repositories, and why we say Onyx never asks for code access rather than that it could never have any. For a public repository the code is public regardless.
Deciding what members can hear
Connect a repository and you make one choice about it:
- Staff only. Onyx never brings this repository up with a member. It still feeds
/githubcommands and the activity channel. This is the default for a private repository. - Members can be told. Onyx can mention its issues when a member describes one.
Then, optionally, Only issues tagged ____. Put a label there and Onyx sticks to the issues carrying it. On a private repository that is the setting worth using: tag the handful of issues you're happy to acknowledge in public, and the rest stay invisible.
A private repository set to "members can be told" with no tag means every open issue is quotable, including the one that pastes a customer's email or a stack trace. Onyx asks you to confirm that combination rather than letting you pick it by accident.
There used to be a third option here called "members see titles and summary", and it was removed rather than renamed. Nobody could tell what a "summary" was, ourselves included: it was mechanically the first 400 characters of the issue body, which is exactly where the things you'd want to keep private tend to live. Depth is now derived instead of chosen. On a public repository the issue body is already public, and on a private one you tagged the issue deliberately, so there's nothing left to decide.
What Onyx sends to GitHub
Every issue Onyx opens is reviewed by a staff member before it exists, and carries a footer naming who confirmed it and where it came from.
Transcripts are never pasted. The issue links to the Onyx transcript instead, which stays access controlled. If your repository is private and you would rather have the report inline, turn on "Quote the member in the issue body" in the drawer.
Setting it up
-
Token. On GitHub: Settings → Developer settings → Personal access tokens → Fine-grained tokens. Select your repositories, set the two permissions above, and paste it into the drawer.
If your repositories belong to an organisation, set Resource owner to that organisation. It is the first dropdown on the token page and it defaults to your own account. A fine-grained token can only reach resources owned by whoever is selected there, so a token owned by you returns "not found" for every organisation repository no matter which repositories you tick underneath. This is the single most common reason the plugin cannot see a repository that plainly exists.
If the organisation is not in that dropdown, it has not opted in yet: an owner of it goes to the organisation's Settings → Personal access tokens and allows fine-grained tokens. If the organisation requires approval, your token is created but stays pending until an owner approves it under Settings → Personal access tokens → Pending requests, and until then it behaves exactly as though the repositories do not exist.
-
Repositories. Add them one at a time as
owner/name, using the organisation's name as the owner rather than yours. Each is checked as it is added. -
Webhook (recommended). Paste the Payload URL from the drawer, set Content type to
application/json, use the secret you saved in the drawer, and under "Let me select individual events" tick Issues, Issue comments and Releases. Without it Onyx still works, it just refreshes on a sweep instead of instantly.If your repositories belong to an organisation, add the webhook once to the organisation rather than to each repository: org Settings → Webhooks → Add webhook. One hook covers every repository in the org, now and in future, so connecting a new repository later needs no webhook work at all. Onyx drops deliveries for repositories you have not connected in the drawer, before they are stored or reach your bot, so an org hook never pulls in a repository you left out.
Only add it per repository when the repositories are on a personal account, where GitHub offers no account-wide hook.
Each box maps to a feature: Issues keeps awareness current and fires the fix notice, Issue comments carries your
/publicprogress updates, and Releases is how the "when a release ships it" option finds out that it shipped. Skip Releases and that option will never fire. -
Roles. Set your read and write roles. Write is what lets someone confirm a drafted issue.
Commands
| Command | Tier | Does |
|---|---|---|
/github issue search | read | Find issues by keyword. |
/github issue status | read | One issue, plus how many tickets reference it. |
/github issue create | write | Open an issue from a form. |
/github issue comment | write | Comment, attributed to you. |
/github issue close | write | Close as completed or not planned. |
/github link | read | Link this ticket to an issue, so the member hears when it closes. |
/github status | read | Diagnostics: repositories, token check, sync state. |
What it costs
Awareness is the feature you will use most, and it is free per message: it reads a local copy of your issues with one indexed query, and adds nothing to the prompt when there is no match. Filing an issue by @-mention costs one small model call, around a tenth of a cent. The daily pattern review is off by default, skips quiet days entirely, and costs roughly the same per run when it does fire. All of it is billed the same way as every other AI action.