Skip to content
chartrandfPublic

About

Watcher of PRs across projects, dispatch review, follow-up and review handling sessions quickly.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Lookout

Your GitHub lookout.


Desktop overview of all your Claude Code review sessions: discover open PRs across hand-picked repos, dispatch review/follow-up sessions, track follow-ups, auto-clear merged PRs.

Tauri v2 + React + TypeScript + Tailwind. No remote server — everything runs locally: the app polls gh, scans ~/.claude/projects/ sessions and each repo's AI_TASKS/code-review/ exports.

⚠️ Opinionated. This app encodes my personal review flow (discover → dispatch a Claude review → push comments → follow up → approve) and has only been tested against my personal commands — it may not fit yours out of the box.

But you can configure the dispatched prompts in Settings → Claude commands (defaults use Claude Code's built-in /review; placeholders <branch_name> and <pr_id> are supported).

Install

Homebrew

This repo doubles as its own Homebrew tap:

brew tap chartrandf/lookout https://github.com/chartrandf/lookout
brew trust --cask chartrandf/lookout/lookout   # Homebrew 6+ gates third-party casks
brew install --cask lookout                    # --force to replace a hand-installed copy

All three lines are required, in order. Homebrew expands a bare chartrandf/lookout to chartrandf/homebrew-lookout, which doesn't exist — so not even the fully-qualified brew install --cask chartrandf/lookout/lookout can tap this repo on its own. Skip the brew tap line and you get Invalid usage: Casks must be fully-qualified / No Cask with this name exists.

Manual

Grab the latest .dmg from Releases (universal — Apple Silicon + Intel) and drag Lookout to Applications.

On Linux (x86_64), grab the .deb (sudo apt install ./Lookout_*.deb) or the .AppImage (chmod +x, then run it).

🔒 Quarantine Issue

The bundle is self-signed, so macOS quarantines it. You may need to release the quarantine manually from the Terminal.

xattr -dr com.apple.quarantine /Applications/Lookout.app

Dev

pnpm install
pnpm tauri dev

pnpm tauri … builds the CLI first (pretauri → pnpm build:cli): tauri.conf.json bundles dist-cli/lookout.mjs as a resource, and the Rust build fails without it.

Requirements — see Tauri's prerequisites for your OS:

  • Linux — the webview/tray system libs, e.g. on Debian/Ubuntu: sudo apt install libwebkit2gtk-4.1-dev build-essential libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
  • Rust (stable) — curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh. Without it pnpm tauri dev dies at cargo metadata … No such file or directory (os error 2).
  • Xcode Command Line Tools (macOS) — xcode-select --install, for the linker cargo shells out to.
  • gh (authenticated) and the claude CLI.

pnpm is pinned by the packageManager field — corepack enable picks up the right version. npm install can't build this tree: package-lock.json is stale, and resolving the missing dev deps from scratch crashes Arborist with Cannot read properties of null (reading 'edgesOut').

Usage

  1. Settings — add local clone paths; owner/repo is detected from each clone's git origin. Your GitHub login is auto-detected; your own PRs are never listed.
  2. Discovery — new open PRs land here. Review (add to board + dispatch /do-review), Watch (add to board), Ignore (hide forever). PRs you already reviewed or commented on skip Discovery.
  3. Reviews — Watching / Needs Review / Reviewed / Follow-up / Done. Drag cards to triage or prioritize. Merged or closed PRs auto-move to Done and drop off after 24 h.
  4. Pull Requests — your own PRs: Waiting / In Review / Ready to merge / Done. A human review moves a card to In Review, an approval to Ready to merge (where the CI tag is all you need to decide). Cards only ever move forward on their own, so re-requesting a review or flipping back to draft can't drop one out of In Review. Bot reviews (Cursor, Sonar) show a 🤖 badge but never move a card — they're lint, not review. Drag anywhere, in either direction: a drop stays put until GitHub itself changes its mind. Done holds what you merged or closed today and empties overnight.
  5. PR panel — click a card: chat-style history (sessions, reports, commits, reviews), dispatch buttons, stage selector, one-click approve when follow-up is all green, resume sessions in Ghostty.
  6. Worktrees — you only ever register the clone path. A branch checked out in a linked worktree is followed there: actions run in that worktree, its sessions and AI_TASKS/code-review/ reports show up on the card, and resume opens the directory the session actually ran in.

Reviews with no report file

A review only reaches a card if something wrote it down. My own /do-review exports AI_TASKS/code-review/<stamp>-<branch>.md, which the app scans — but the default review button runs Claude Code's own /review, which prints its verdict and saves nothing. Those cards used to show a session and no review.

Lookout now reads the review back out of the session transcript itself (the final assistant turn) and keeps it for 30 days. Follow-up runs are captured the same way and labelled as follow-ups. It is display only: a captured review never moves a card and never raises an alert. Settings → Capture reviews has the switch, the count and a Clear button.

A branch whose reviews are exported to AI_TASKS/code-review/ is left alone — the file is used and nothing is captured, so a review can't appear twice. A session that wrote its own report is skipped for the same reason.

Capture happens on the next sync. For it to land the moment a session stops, copy the Stop hook from Settings into ~/.claude/settings.json:

{ "hooks": { "Stop": [{ "hooks": [{ "type": "command", "command": "lookout review capture --hook", "timeout": 10 }] }] } }

A skill can also hand a review over outright, which always wins over what Lookout guessed:

lookout review report --file AI_TASKS/reviews/pr-2305.md   # a report file living anywhere
claude -p "…" | lookout review report --stdin              # or the text itself

lookout CLI

The Homebrew cask puts a lookout command on your PATH — brew install --cask lookout symlinks it, nothing else to do. Installing the DMG by hand instead leaves it inside the bundle at Lookout.app/Contents/Resources/lookout; symlink it yourself:

ln -sf /Applications/Lookout.app/Contents/Resources/lookout ~/.local/bin/lookout

It runs on Node 22.13+ (or 23.4+), where node:sqlite stopped needing a flag. In a dev checkout: pnpm build:cli, then symlink dist-cli/lookout.mjs. It moves cards from a terminal, so a Claude Code skill can report back once it has pushed comments — and it works whether or not the app is open, because it writes the same SQLite database the app uses.

The command name says whose work it is: review for other people's PRs (the review pipeline), mine for your own (the merge pipeline).

lookout review list --stage "in review"    # what's in a column
lookout review show --pr 2305              # one card, or omit the selector inside a repo checkout
lookout review reviewed                    # the PR for this repo + branch → Reviewed
lookout review comments-pushed --count 3   # what /do-review calls after `gh api .../reviews`
lookout review report --file report.md     # register a report your skill wrote, wherever it wrote it
lookout review capture --hook              # Stop-hook entry point: payload on stdin, always silent

lookout mine list --column ready           # my PRs that are approved and just need a CI check
lookout mine show                          # my PR for this repo + branch
lookout mine ready                         # → Ready to merge

lookout stream add "#app implement card 1,2"   # dump work onto the Stream board (--queue for Queued)
lookout stream list --status needs_review      # what waits on me
lookout stream gate --summary "Plan ready"     # an agent stops for my review (--kind question to ask)
lookout stream note "tests are slow here"      # a line in the item's trail

lookout doctor                             # database path and both board counts

Stages and columns are named the way the board names them — needs-review, "In Review", follow-up, "Ready to merge", case and spacing ignored. Retired names still resolve (inbox is now needs_review, and lookout card … is the old spelling of lookout review …), so older scripts and shell aliases keep working.

A card is picked by --id <id>, --pr <n> or --branch <b> (add --repo owner/repo to disambiguate); with no selector at all it uses the current checkout's origin and branch. Moves on both boards are forward-only — the app's own rule, so an automated caller can't drag a card backwards — with --force to override. --json for machine output, --dry-run to resolve without writing.

Exit codes are the contract for scripts: 0 done · 1 error · 2 no matching card · 3 Lookout has never run here · 4 selector matched several cards. In a skill, guard on the binary and let the "nothing to do" codes pass:

command -v lookout >/dev/null && lookout review comments-pushed --branch "$BRANCH" --count 3 --quiet || true

When the app is running it repaints immediately: the CLI pings a unix socket the app publishes next to the database, and the app re-reads. The event is only a hint — every failure degrades to the app noticing at its next sync.

Font

Bundles Leckerli One (SIL Open Font License 1.1).

License

MIT

About

Watcher of PRs across projects, dispatch review, follow-up and review handling sessions quickly.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages