Skip to main content

Read-only GitHub reviewer CLI: triage, re-review diffs, comment threads

Project description

twgh

Read-only GitHub reviewer CLI — for humans and agents.

Triage what needs you, re-review only what changed since you last looked (force-push robust), and see which of your comments were addressed. Works across github.com and GitHub Enterprise.

twgh never writes to GitHub — no approvals, no comments, no merges. It is the read side of reviewing; for write actions it hands you off to the browser.

Every command produces clean, pipeable output: --json where the data is tabular, unified diff hunks where the data is code. No wrapper needed — twgh status --json | jq and twgh diff 42 | llm "summarise" work out of the box. This makes twgh equally useful as a human terminal tool and as a building block in agent and CI pipelines.

Install

From PyPI (requires Python ≥ 3.12):

uv tool install twgh      # or: pipx install twgh

From source:

make install      # uv tool install -e . + bash completion

Prerequisites

  • The GitHub CLI gh, authenticated for each host you review on: gh auth login --hostname <host>. twgh borrows gh for auth, host routing, and transport; it never handles your token.

Commands

twgh status — which PRs need me right now?

twgh status
twgh status --json
twgh status --author "dependabot[bot]"

Cross-repo rollup of every open PR you are review-requested on, commented on, or have reviewed. Per PR: author, your review state against the current head (needs_review / needs_re_review / up_to_date), and open-thread count. ★ marks PRs that moved since your last status run — new head or new comments, tracked via a local snapshot (the first run deliberately flags nothing).

Option Description
--json Machine-readable JSON array — one object per PR
--author <user> Show only PRs by this author (overrides exclusion list)

twgh diff — what changed since I last looked?

twgh diff <ref>
twgh diff <ref> --all
twgh diff <ref> --comments
twgh diff <ref> --web

The author pushed again; you don't want to re-read the whole PR. diff anchors on your last submitted review (else your last inline comment) and shows anchor→HEAD, restricted to the files you commented on. The anchor is a commit OID, so the diff survives force-pushes and rebases. With no prior review there is nothing to re-diff — it points you at twgh open instead.

Output is unified diff text, paged through delta / $PAGER / less -R. When stdout is not a TTY (piped or redirected), the pager is skipped and raw diff text goes to stdout — ready for grep, patch, or an LLM.

Option Description
--all Show the whole-PR diff, not just files you commented on
--comments / -C Weave your inline review comments into the diff as # -prefixed context above each file's patch
--web Open the anchor→HEAD range in GitHub's compare view instead of the pager. A force-push-safe deep-link the web UI can't construct by hand. File-scoping and --all do not apply

twgh compare — diff between two arbitrary commits

twgh compare <base> <head>
twgh compare <base> <head> --web
twgh compare abc123 def456 --repo LOS/my-repo

Show the diff between any two commits. Both short and long SHA forms are accepted — GitHub's API and web UI resolve them server-side. Repo context comes from the current directory's git remote; use --repo to override.

Same output behaviour as diff: paged for humans, raw text when piped.

Option Description
--web Open the compare view in the GitHub web UI (/compare/<base>..<head>)
--repo / -R <owner/repo> Repository override — use instead of CWD git context

twgh threads — were my comments addressed?

twgh threads <ref>
twgh threads                    # global inbox (no ref)
twgh threads <ref> --mine
twgh threads <ref> --by alice
twgh threads <ref> --all

An action-oriented triage view: one row per review conversation with a verdict showing whether it still needs attention:

  • ✓ resolved — the thread is marked resolved
  • ~ changed — the anchored code moved since the comment (inspect with twgh diff)
  • · untouched — the point still stands as written

Omit <ref> for a global inbox of open threads across all PRs that involve you.

Option Description
--mine Only threads you opened
--by <user> Filter by thread author
--all Include resolved threads

twgh comments — what was said while I was away?

twgh comments <ref>
twgh comments <ref> --mine
twgh comments <ref> --by carol
twgh comments <ref> --all

A chronological reading view of everything said on a PR: top-level comments and inline review comments, sorted by time. Think of it as a chat log — you read top to bottom to understand the full conversation timeline. Comments in resolved threads are hidden by default.

Option Description
--mine Only your comments
--by <user> Filter by comment author
--all Include inline comments in resolved threads

threads vs comments

Both draw from the same PR data but serve different workflows:

threads comments
Unit one row per conversation one row per comment
Order by file path by time
Key info actionable verdict full message body
Question answered "what needs my response?" "what was said?"
Scope single PR or global inbox single PR only

twgh open — hand off to the browser

twgh open <ref>

Opens the PR in the browser for the write actions twgh stays out of: approving, replying, resolving, merging.

twgh edit — configure twgh

twgh edit --init    # create starter config and open in $EDITOR
twgh edit           # open existing config in $EDITOR

Opens the config file in $EDITOR. Use --init to bootstrap a starter config if one doesn't exist yet.

PR references

<ref> is a PR URL, host/owner/repo#N, owner/repo#N, owner/repo/N, or a bare number inside a repo checkout. status prints URLs — paste them straight back.

Host selection

-H/--gh-host overrides $GH_HOST, which defaults to github.com. Works as a global option (twgh -H bmw.ghe.com status) or per command.

Configuration

Optional TOML config at ~/.config/twgh/config.toml (override with --config). Bootstrap a starter with:

twgh edit --init

Author exclusion

Hide PRs from bots/service accounts in status and threads (inbox mode):

[exclude]
authors = ["dependabot[bot]", "self-hosted-renovate[bot]"]

# Per-host additions (extends the global list):
[exclude."github.enterprise.com"]
authors = ["renovate-enterprise[bot]"]

Override the exclusion list to show a specific author:

twgh status --author "dependabot[bot]"

Output conventions

twgh uses two output formats, chosen by what the data naturally is:

Data shape Format Commands
Tabular (PR list, thread verdicts) Rich table (human) or --json (machine) status, threads, comments
Code delta Unified diff text with @@ hunks diff, compare

Diff output is already structured — @@ markers delimit hunks, +/- prefix changed lines, file headers name each path. Any downstream tool, LLM, or agent can parse it without a JSON wrapper. Piping works naturally: the pager is skipped when stdout is not a TTY.

Development

make test              # pytest + coverage (floor 85%)
make static-analysis   # ruff lint-fix, format, ty

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

twgh-0.3.0.tar.gz (22.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

twgh-0.3.0-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

Details for the file twgh-0.3.0.tar.gz.

File metadata

  • Download URL: twgh-0.3.0.tar.gz
  • Upload date:
  • Size: 22.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for twgh-0.3.0.tar.gz
Algorithm Hash digest
SHA256 5cf1e11efa6b0454273b8b9ee05bf9a4067e2042dd09c3644289363cc3b29fb5
MD5 2b1af88ccb885d0a1f3160a99d4234ae
BLAKE2b-256 fd341a737a0080c0c7d8f692213ccaba1443d63e89e7e2b0cbee3332be160fa5

See more details on using hashes here.

File details

Details for the file twgh-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: twgh-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 22.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for twgh-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c1747e64f88dc3e94c48bae009e78260f89a1a101730e0ad92b1ac1c8b01fc21
MD5 70b883faccb29f7a06e5bd6cb74cd190
BLAKE2b-256 ed78d063a03dda5c72111fdb0e928b6b02f13ca037b12b1b36c58436185e413c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page