AI Inbox
A daily, plain-English triage of your open PRs and Linear issues — ranked, summarised, and sent off-device for the model to look at. One free triage a day; unlimited on Pro.
The AI Inbox reads your open PRs and Linear issues, ranks them by what actually needs you next, and writes a short summary you can scan in three seconds. The model does the thinking; your tokens stay in your browser. Made for the mornings where you don't know where to start.
Two urgent items today — the billing-migration PR is blocking staging, and ENG-218 has been escalated twice.
- Review acme/web#412 — billing migrationGitHub blocking the staging deploy.
- ENG-218 — onboarding skips empty workspacesLinear flagged by support twice this week.
- Review acme/api#127 — cache invalidationGitHub small diff; reviewed v1 last week.
What it does, exactly
The widget pulls the same data the GitHub and Linear widgets do — open PRs where you're a reviewer, open issues assigned to you — and posts a minimal slice of each item to a butter-hosted Edge Function. That function runs the data through OpenAI, asks for a short summary plus a ranked list of actions, and hands the structured response back.
What you see in the widget is the model's output, not its input: a paragraph summary up top ("Two PRs are blocked on you, one is from your teammate Jess and is a one-line fix"), then a ranked list of items with a priority badge, a tappable link, and a short why line.
Setting it up
- You need a butter account. The widget reads the Account section of the global settings — sign in via the , Settings panel before adding the widget, or you'll see Sign in to butter instead of triage.
- Free gets one successful triage a day. The Edge Function enforces the cap on a 24-hour rolling window, server-side. A row is recorded only after a successful OpenAI response, so a flaky LLM call never burns your free daily allotment. When the cap is hit the widget keeps showing your most recent triage and surfaces when the next run unlocks; an inline Upgrade button takes you straight to checkout.
- Pro is unlimited. Pro accounts skip the quota check entirely — refresh as often as the cache TTL allows.
- You need at least one source connected. If neither GitHub nor Linear is connected via the global Settings → Connections panel, the widget tells you so. Connect at least one and it kicks in automatically on the next open.
Privacy: what gets sent
Triaging requires the model to see something — but only as much as is needed for the call. The widget posts a deliberately minimal payload:
- For each PR: title, URL, repo name, author username, updated-at timestamp, and the draft flag. Not the diff, review comments, commit history, or any private repo content beyond the title.
- For each Linear issue: identifier, title, URL, team key, current state name, priority, and updated-at timestamp. Not the description, comments, sub-issues, or attachments.
- For your butter session: a Supabase JWT Authorization header. The Edge Function validates it, checks your quota or Pro status, and uses it once. The model never sees the token.
The Edge Function passes the payload to OpenAI, gets the structured response back, and returns it to you. We do not log the payload, we do not retain it after the call, and OpenAI does not train on it (per OpenAI's API data policy). If you'd rather not use any of this, leave the widget off — every other widget in butter runs without any off-device LLM calls.
Settings
| Setting | Type | Default |
|---|---|---|
| Include GitHub PRs Feeds your PRs (the ones the GitHub widget would show under "Review requested") into the triage. Off skips them entirely — no fetch, no token use. | toggle | on |
| Include Linear issues Feeds your Linear issues (the ones assigned to you) into the triage. Off skips them entirely. | toggle | on |
| Maximum actions Caps how many ranked actions appear in the list, between 3 and 30. The model may return more or fewer — this is just the display cap on the widget side. | integer | 10 |
| Show priority Filters which priority tiers reach the displayed list. Useful for keeping the widget short on busy days — set to "High only" to see just the genuinely urgent stuff. | All · Medium and above · High only | All (Low and above) |
| Cache for (minutes) How long to reuse a triage before calling the model again, between 5 and 720 minutes. Hit the refresh icon to force a fresh run inside the window. The triage runs against OpenAI; caching keeps your usage low. | integer | 60 |
Small things you might miss
- The cache is namespaced to your account. If you sign in as a different butter user (rare, but possible), the cached summary is ignored — no cross-account leak via a stale cache.
- Sources can be turned off independently. Off-toggled sources don't fetch and don't ride along to the model. Useful if you've connected Linear but only want PR-driven triage today.
- Empty inboxes celebrate. If neither source has any open items, the widget says Inbox zero and doesn't burn a model call. The Edge Function is also defensive — empty arrays in, a short empty response back.
- Each action has a "why." The model is asked to include a one-line rationale for every ranked action ("Author flagged you as a reviewer 2 days ago"). That line lives in the metadata row under the title.
Heads up
- OpenAI calls take time. A cold triage on a busy queue can spend 20–30 seconds inside the Edge Function while the model thinks. The widget shows a loading state and a 45-second outer timeout, so it can't spin forever — but it also won't be instant.
- Session expiry is detected. If your butter sign-in expires mid-session, the next refresh shows a sign-in CTA inside the card. One click signs you back in via Supabase.
- Pro lapse is graceful. If your subscription expires, you drop back to the free tier's one-a-day cap automatically — no surprise paywall in the middle of the day. The widget keeps the most recent triage cached and shows when the next free run unlocks.
- This is the only widget that calls our servers. Every other widget either runs locally (Clock, Pomodoro, Todo, Scratchpad, Quote) or calls the source's API directly (GitHub, Linear, HN, Reddit, Weather, Quick Links favicons). The AI Inbox is the single exception — and it has to be, because the model lives on our side.