What It Does
Lookout sits silently in the menu bar as a binoculars icon. When something on GitHub needs you, the icon switches to a red-tinted filled variant and slowly pulses until the items are resolved.
Click the binoculars to drop a popover with the items grouped by repository — each row showing the kind, title, and how long ago it was updated. Click any row to open it on github.com. The popover’s footer has a Mark all read button that calls GitHub’s notifications API to clear unread state in one sweep.
Five Sources, One Inbox
Lookout polls five GitHub queries concurrently and dedupes the results into a single list:
| Source | What it covers |
|---|---|
| Notifications API | The unified feed: mentions, review requests, assigns, comments, state changes, CI activity on subscribed threads |
| Review requested | Open PRs awaiting your review |
| Failing CI on your PRs | Your own open PRs with at least one failing check |
| Issues and PRs on repos you own | Anything open on a repository you own, whether or not you watch it |
| Discussions on repos you own | Open discussions on a repository you own, answered and locked ones excluded |
The last two exist because the notifications inbox only fires for repositories you are subscribed to, and owning a repository does not subscribe you to it. Somebody opens an issue, a pull request or a discussion on a repository of yours that you do not watch, and GitHub tells you nothing at all.
All three kinds are now covered. Discussions needed a different approach from the other two: GitHub’s REST search does not index discussions, so that one query runs against the GraphQL API instead.
An item from those two rows is listed only while the last person to act on it was not you. A new thread qualifies, and it drops off once you reply, until the other party responds again. Reacting counts as replying, so a thread you have acknowledged with an emoji stops asking for your attention.
Lookout checks GitHub every minute by default, and you can set any interval from 1 to 360 minutes in Settings. It never checks more often than GitHub’s own recommended interval (usually 60 seconds), and it uses If-Modified-Since so that a check with no changes does not use rate-limit budget. Checking pauses when the system sleeps and resumes, with an immediate refresh, on wake.
If GitHub rate-limits a check, Lookout waits and tries again on its own, and tells you when. It waits as long as GitHub asks, or 2 minutes, doubling each time the limit repeats, up to an hour. Each check sends several searches at once, and GitHub’s secondary rate limit applies to bursts, so a longer interval makes a limit less likely.
Setup
Lookout needs a classic GitHub Personal Access Token. Fine-grained PATs do not work with GitHub’s Notifications API and are rejected by the server.
- Create a token at github.com/settings/tokens/new with these scopes:
notifications,repo(orpublic_repoif you only watch public repositories),read:user. - Launch Lookout. A setup sheet asks for the token. Paste it and click Save.
- The token is validated against
GET /user, then stored in your macOS Keychain (servicecc.jorviksoftware.Lookout). It is sent only toapi.github.com.
To replace the token later: right-click the menu-bar icon → Re-enter GitHub Token…
Controls
| Action | Result |
|---|---|
| Left-click binoculars | Open the items popover |
| Right-click binoculars | Standard Jorvik menu (About, Refresh, Re-enter Token, Check for Updates, Settings, Quit) |
| Click an item row | Open it on github.com |
| Refresh button | Check GitHub now, whatever the interval in Settings |
| Mark all read | Clear every GitHub notification (calls PUT /notifications) |
Settings
Right-click the icon and choose Settings… to configure:
- Refresh — how many minutes Lookout waits between automatic checks, from 1 to 360 (1 by default). The stepper applies each click; a typed number applies when you press Return or click Done. A change moves the next check and does not start one
- Menu bar icon pill — optional grey background for stronger contrast on busy or wallpaper-tinted menu bars (off by default)
- Launch at Login — start automatically when you log in
Auto-updates are handled by Sparkle. Use the “Check for Updates…” menu item to check on demand; Sparkle’s prompt offers an “Automatically download and install updates in the future” checkbox the first time an update is available. Lookout checks for new versions automatically once a day in the background.
Installation
Two formats on every release — both signed and notarised, pick whichever suits:
- Installer (
.pkg) — recommended for first-time installs. Double-click to run; macOS Installer places the app in/Applicationswithout quarantine or App Translocation. - Download (
.zip) — unzip and dragLookout.appto your Applications folder.
Or install it with Homebrew: brew install --cask perpetualbeta/jorvik/lookout
After installation, launch Lookout — a binoculars icon appears in the menu bar. On first launch a sheet asks for your GitHub token (see Setup above).
Privacy
- No telemetry. No analytics. No ads. No subscriptions.
- The PAT lives in your macOS Keychain and is never written to disk in plain text.
- Network traffic goes only to
api.github.com.
Building from Source
Lookout is a Swift app with no dependencies beyond macOS system frameworks. No Xcode project is required.
- Clone the repo:
git clone https://github.com/PerpetualBeta/Lookout.git - Run
gmake build - Launch with
open .build/Lookout.app
gmake build drives the shared release.mk pipeline — compiles the Swift sources with swiftc, links against Cocoa, SwiftUI, ServiceManagement, and Security, and signs the bundle with the Developer ID identity.
Requirements
- macOS 14 (Sonoma) or later
- A GitHub classic Personal Access Token (see Setup)
