loupe

module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 16, 2026 License: MIT

README

loupe

ci release

loupe files pull request review findings for a human to decide and publish.

  1. An agent captures the pull request into a local draft and files findings.
  2. You decide each finding in loupe review.
  3. loupe publish posts exactly one confirmed GitHub review.

Install

export GITHUB_TOKEN="$(gh auth token)"
mise use -g github:eriksaulnier/loupe@latest
loupe --version
  • Token: the repository is private, so mise needs a GitHub token to download the release. On macOS gh keeps its token in the keychain, where mise cannot read it, so export it in your shell profile.
  • A release cut today fails with no versions found for github:eriksaulnier/loupe matching date filter, because mise hides releases younger than its minimum_release_age. Wait, or exempt loupe: mise settings add minimum_release_age_excludes "github:eriksaulnier/loupe".

Agent plugin

One plugin for Claude Code, Codex and Pi. Its human-review skill is the workflow a review skill or agent follows: capture the pull request, file findings, hand the run to you, and answer your send-back notes. It brings no review method of its own.

# Claude Code
claude plugin marketplace add eriksaulnier/loupe
claude plugin install loupe@loupe

# Codex
codex plugin marketplace add eriksaulnier/loupe
codex plugin add loupe@loupe

# Pi, pinned to the release; use the version loupe --version prints
pi install git:github.com/eriksaulnier/loupe@v0.6.0 # x-release-please-version
  • Keep plugin and binary together. Claude Code and Codex install the plugin from main, so a skill can name a flag an older binary lacks.
  • Private repository: Codex and Pi clone with git, which needs github.com credentials, such as those gh auth setup-git configures.
  • Codex sandbox: loupe cannot reach GitHub, the clone's .git, its data directory or the Herdr socket from inside it. Approve the skill's requests to run loupe outside the sandbox. Pi has no sandbox.

Review in a Herdr pane

Inside Herdr, loupe handoff opens loupe review in a split beside the agent's pane, and the pane closes when review exits cleanly. Elsewhere, or when the split fails, the skill asks you to run loupe review yourself.

To skip the approval prompt at each hand-off, allow that one command:

  • Claude Code: Bash(loupe handoff:*)
  • Codex, in ~/.codex/rules/default.rules: prefix_rule(pattern=["loupe", "handoff"], decision="allow")

loupe builds the pane's command from the run it resolves, so the rule lets an agent open review and nothing else. Do not allow herdr pane split or herdr pane run: a blanket rule for either lets any command run in a new shell.

Commands

loupe --help is the reference, and every command's --help shows its JSON input and result.

Who Command What it does
agent capture Capture a pull request into a new review round
agent add File findings into the draft
agent summary Set the review summary
agent handoff Open review for the human in a new Herdr pane
agent wait Block until the human hands notes back or publishes
agent edit Change, withdraw or restore a finding
agent reply Answer a send-back note
agent feedback Read the human's notes, dispositions and readiness
anyone show Show the draft, dispositions and readiness
anyone list List every run with its state and counts
human review Decide each finding in the review interface
human publish Confirm and post the review to GitHub

Environment

Variable Meaning
LOUPE_HOME Where runs are stored; the default is $XDG_DATA_HOME/loupe, else ~/.local/share/loupe
LOUPE_RUN The run a command acts on when it names none
LOUPE_LOCK_TIMEOUT_MS How long to wait for a run's lock; default 3000, maximum 60000
LOUPE_ICONS ascii, unicode (default) or nerd (needs a Nerd Font); a non-UTF-8 locale always gets ASCII
NO_COLOR, TERM, LANG/LC_ALL Honored for color, plain-mode fallback and glyph selection
GH_TOKEN, GITHUB_TOKEN The github.com token, checked in that order; without either, loupe uses the one gh auth login stored

contracts/cli.md has the exact rules and refusals for the LOUPE_ variables.

Unattended publish

A pipeline reviews a pull request with no human and no terminal: capture, file, publish. Capture is the only step that needs the Git clone.

  1. loupe capture <pr-url> --json creates the run and prints its reference as run. Pass that reference to the later steps, either as --run <ref> or by exporting it as LOUPE_RUN; unattended publish will not fall back to the pull request of a branch, since a pipeline's checkout is usually not sitting on it.
  2. Something files findings and a summary through the input any agent uses: one loupe add object or array, stored entirely or not at all, and one loupe summary, set even when there is nothing to report. A finding whose location is not in the captured diff is refused with the nearest valid lines. loupe ships no adapter that turns a reviewer's output into this shape; a pipeline supplies its own, and this feature names no particular review action.
  3. loupe publish --unattended --json posts exactly one comment review, with no confirmation and no terminal, once the resolved token is a GitHub App installation token: the ghs_ prefix, which is what Actions' own GITHUB_TOKEN carries. The token needs permissions: pull-requests: write; a user token here refuses with token. Restoring the data root at a different path, even on a different machine, replays a receipt or reconciles an unknown attempt, so a pipeline that persists LOUPE_HOME between steps can retry safely.

.github/workflows/review.yml is a worked example: it builds loupe from main, captures a pull request named by hand, runs an agent over the captured head and diff, and publishes unattended.

Try it without a pull request

In a clone, mise run demo opens loupe review on seeded runs against an in-memory GitHub, so the interface and the whole publish flow, y included, can be tried end to end. Nothing leaves the machine. mise run demo -- <loupe args> runs any other command: acme/widgets#42 is mid-review, #43 is ready to publish, and #44 is ready with a moved head.

Contributing and releases

CONTRIBUTING.md covers setup, local development, tests and commits. release-please opens the release PR, merging it tags the release, and goreleaser attaches the archives and checksums.txt. Nothing is tagged or released by hand.

Reference

License

MIT. See LICENSE.

Directories

Path Synopsis
cmd
loupe command
loupe-demo command
Command loupe-demo runs loupe against seeded review runs and an in-memory GitHub, so the review interface and the whole publish flow can be tried by hand without a pull request, credentials or network.
Command loupe-demo runs loupe against seeded review runs and an in-memory GitHub, so the review interface and the whole publish flow can be tried by hand without a pull request, credentials or network.
internal
cli
Package cli maps loupe's commands onto cobra and turns domain results and refusals into the output contract.
Package cli maps loupe's commands onto cobra and turns domain results and refusals into the output contract.
diff
Package diff is the parsed pr.diff that both location validation and the review interface read.
Package diff is the parsed pr.diff that both location validation and the review interface read.
draft
Package draft holds the review draft: findings, human decisions, send-back notes and replies.
Package draft holds the review draft: findings, human decisions, send-back notes and replies.
findingid
Package findingid orders ids like f-001 so that f-999 sorts before f-1000.
Package findingid orders ids like f-001 so that f-999 sorts before f-1000.
gitenv
Package gitenv filters the environment handed to git, shared by gitx and the test repositories.
Package gitenv filters the environment handed to git, shared by gitx and the test repositories.
github
Package github is loupe's narrow view of the GitHub REST API, behind an interface so tests can fake it.
Package github is loupe's narrow view of the GitHub REST API, behind an interface so tests can fake it.
gitx
Package gitx runs the few git commands loupe needs against the user's clone.
Package gitx runs the few git commands loupe needs against the user's clone.
markdown
Package markdown checks authored Markdown against the allowlist in docs/comment-format.md, so a body or summary cannot restructure the <details> wrapper the renderer puts around it.
Package markdown checks authored Markdown against the allowlist in docs/comment-format.md, so a body or summary cannot restructure the <details> wrapper the renderer puts around it.
pane
Package pane opens loupe review for the human in a new Herdr split beside the agent's pane.
Package pane opens loupe review for the human in a new Herdr split beside the agent's pane.
publish
Package publish runs the publication state machine: gates, envelope, confirmation, one review request, receipt.
Package publish runs the publication state machine: gates, envelope, confirmation, one review request, receipt.
refusal
Package refusal is a leaf so every domain package can return refusals without importing internal/cli.
Package refusal is a leaf so every domain package can return refusals without importing internal/cli.
render
Package render composes what loupe shows and sends.
Package render composes what loupe shows and sends.
run
Package run owns the on-disk layout of review runs: paths, references, atomic writes and locking.
Package run owns the on-disk layout of review runs: paths, references, atomic writes and locking.
style
Package style is the one place terminal appearance is decided: colors, glyphs and the small layout helpers every human-facing surface shares, so the review interface and the one-shot commands look like one program.
Package style is the one place terminal appearance is decided: colors, glyphs and the small layout helpers every human-facing surface shares, so the review interface and the one-shot commands look like one program.
testutil/fakegh
Package fakegh is an in-memory GitHub REST server for the endpoints loupe calls, reached through the production client so request encoding is exercised end to end.
Package fakegh is an in-memory GitHub REST server for the endpoints loupe calls, reached through the production client so request encoding is exercised end to end.
testutil/gitrepo
Package gitrepo builds a local stand-in for a GitHub repository: a bare remote, a user's clone of it, and a pull request head published at refs/pull/<number>/head.
Package gitrepo builds a local stand-in for a GitHub repository: a bare remote, a user's clone of it, and a pull request head published at refs/pull/<number>/head.
tui
Package tui is the human review interface: a full-screen Bubble Tea program and a line-by-line plain mode.
Package tui is the human review interface: a full-screen Bubble Tea program and a line-by-line plain mode.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL