AI Inbox — butter docs Skip to content
Widgets / Your work

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.

AI · free + 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.

Free · 1 / day Pro · unlimited 8×4 default 1-hour cache, configurable
AI Inbox
AI Triage 2m ago

Two urgent items today — the billing-migration PR is blocking staging, and ENG-218 has been escalated twice.

  • Review acme/web#412 — billing migration
    GitHub blocking the staging deploy.
  • ENG-218 — onboarding skips empty workspaces
    Linear flagged by support twice this week.
  • Review acme/api#127 — cache invalidation
    GitHub 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.

Completing, dismissing, and personalized ranking

Hover any row and two actions appear on the right: Mark as complete (the check) and Dismiss (the X). Complete and Dismiss clear the item from the list; clicking a title to open it counts as an interaction too. Each of these does two things at once:

  • It's recorded server-side. The event lands in our ai_inbox_interactions table with the item's title, author, repo, team key, priority, and source. Future triage runs read your last 30 days of these into the prompt, so the model learns what you tend to act on versus dismiss.
  • It trains an on-device ranker. A click boosts similar items by 10%, a complete by 15%, and a dismiss penalises them by 8% — tracked as per-author, per-repo, per-team, per-priority, per-source, and time-of-day weights. Weights decay back toward neutral weekly so a stale habit doesn't haunt you, and they live in chrome.storage.local (local:ai-inbox-weights) — they never leave your device.

Once you've logged more than five interactions, the ranker kicks in: it re-orders items within each priority tier — the model's High / Medium / Low grouping is preserved, but inside a tier, the PRs from the teammate you always review float above the bot noise you always dismiss. When it's active, the widget shows a "Personalized based on N interactions" badge above the list so you know the order isn't purely the model's.

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 triage payload, we do not retain it after the call, and OpenAI does not train on it (per OpenAI's API data policy).

One thing is retained, and we want to be precise about it: interaction events. When you click, complete, or dismiss an item, we store that event server-side — the item's title, author, repo, team key, priority, and source — and feed your last 30 days of them back into future triage prompts so the ranking improves. That's the personalization mechanism described above, and it means item titles you've acted on do live on our side, unlike the triage payload itself. If you'd rather not use any of this, leave the widget off and turn off notifications under Settings → Notifications — the background check runs the same triage even without the widget. The only other widget with an off-device LLM call is the Calendar's Pro AI meeting brief.

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

Desktop notifications

The AI Inbox also drives desktop notifications — and this part is a global setting, not a widget setting. It's a single Enable notifications toggle under Settings → Notifications, and it runs whether or not the widget is on your dashboard: with a provider connected, a background check watches your inbox and fires a Chrome notification when something new needs you, urgent items called out first.

  • One toggle, no scheduling homework. No frequency picker, no quiet-hours matrix — flip it on and butter handles the cadence. Flip it off and the background alarm is cleared entirely, not just muted.
  • You're only told about new things. butter remembers what it has already notified you about and stays quiet until something actually changes — opening fifty tabs doesn't re-fire the same alert.
  • Background checks never spend your triage. The scheduled check reads your most recent triage if it's fresh, and otherwise falls back to raw item counts — it never burns your free daily AI run in the background. Your quota is yours.
  • There's a "Send test notification" button in the same panel, so you can confirm Chrome is actually showing them before you rely on it.

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 isn't the only path to our servers — but it's the biggest one. Most widgets either run locally (Clock, Pomodoro, Todo, Scratchpad, Quote) or call the source's API directly (GitHub, Linear, HN, Reddit, Weather, Quick Links favicons). The exceptions: the AI Inbox triage and its interaction tracking, the Calendar widget's Pro AI meeting brief (ai-meeting-prep), and the signed-in-only product analytics. The full enumeration lives on the Privacy & data page.