After Dark Systems / Service Automation HubCompletely Programmable Infrastructure

OpenSAH / Accessible tooling

prtool.

A read-only command-line viewer for GitHub pull requests and GitLab merge requests. It prints one labelled field per line and a diff whose + and - markers stay in the text, so colour is never the only signal.

Version 1.0.0 No tags or releases No license file yet

License. The source repository is public, but it does not include a license file yet. Until one is added, no license is granted to copy, modify or redistribute prtool.

What it is

prtool shows pull requests and merge requests in a terminal. It asks the GitHub CLI (gh) or the GitLab CLI (glab) for the data, then prints it in a form designed to work by speech, braille and magnification as well as by sight.

  • view prints one labelled field per line: the field name, then its value. Field names are never coloured or bold.
  • diff draws a diff with a stat header, line numbers and the + and - markers kept in the text. Colour reinforces the markers; it never replaces them.
  • A piped prtool diff with no colour, bold or view flag is the patch itself, so patch or git apply can apply it.
  • It is read-only. It runs only the view, list and diff subcommands of gh and glab. It never comments, approves, merges or edits.

Requirements

  • Go 1.23 or later to build (go.mod declares go 1.23.0). The only module dependency is golang.org/x/term.
  • gh, signed in, for GitHub pull requests.
  • glab, signed in, for GitLab merge requests.
  • less for the default pager. It is optional; see the pager.

prtool uses whatever authentication gh and glab already have. It stores no tokens of its own.

Build and install

There is no packaged release or tag. Build from a clone:

git clone https://github.com/afterdarksys/prtool.git
cd prtool
go test ./...
go build -o prtool .
./prtool --version

The version line is prtool 1.0.0. Copy the binary to a directory on your PATH, for example $HOME/.local/bin. The Go module path is prtool, so go install from a URL does not work yet.

Quick start

These commands read a public repository and need only a signed-in gh:

prtool view 14629 --repo cli/cli
prtool diff 14629 --repo cli/cli --stat
prtool diff 14629 --repo cli/cli --unified
prtool list --repo cli/cli --limit 10

view prints labelled lines such as these:

title           docs(skills): add task triggers and newer capabilities to gh skill description
state           OPEN
isDraft         no
reviewDecision  REVIEW_REQUIRED
additions       +1
deletions       -1
url             https://github.com/cli/cli/pull/14629

Inside a repository checkout, leave out the number to use the current branch’s request, and leave out --repo to use the checkout’s remote. A number, a full URL or a branch name all select a request. To save a patch for review or to apply it:

prtool diff 14629 --repo cli/cli > change.patch
git apply --check change.patch

Reading the output

Colour and weight

On a terminal, values are coloured unless NO_COLOR is set or TERM=dumb. In a pipe, there is no colour unless you ask for it.

FlagEffect
--colorsColour even in a pipe, and even when NO_COLOR is set.
--boldBold values without turning colour on. It applies even when NO_COLOR is set, so it gives weight for magnification or large print without colour.
--rawThe applicable patch, even on a terminal. It cannot be combined with --stat, --name-only or --side-by-side.

Diff layout

A terminal at least 160 columns wide gets a two-column, side-by-side diff by default. With a screen reader, a braille display or high magnification, add --unified to keep one column at any width. --stat prints only the summary, and --name-only prints only the paths, one per line. --exclude GLOB leaves out matching files and can be repeated.

The pager

Long output on a terminal goes to less -FRX. Set PRTOOL_PAGER to use another command, split on spaces. An empty PRTOOL_PAGER or --no-pager turns the pager off, which some screen readers handle better.

Exit codes

prtool exits 0 on success. Its own errors, such as a missing gh or glab or an invalid flag, exit 1. When gh or glab itself fails, for example on a request that does not exist, prtool exits with that tool’s exit code. Errors are printed on standard error.

Commands

CommandPurpose
view [number|url|branch]One request, one labelled field per line.
list (also ls)Requests in aligned columns, 30 by default. Filter with --state open|closed|merged|all, --author, --label, --search, --base, --head, --assignee, --reviewer, --draft or --not-draft, and set the count with --limit.
diff [number|url|branch]The patch, or a drawn diff on a terminal.
fieldsThe field names that --fields accepts, one per line.

prtool pr ... forces GitHub and prtool mr ... forces GitLab. An explicit --host github or --host gitlab wins over either. Run prtool COMMAND --help for each command’s flags.

Fields

--fields a,b,c chooses what view and list show, and --fields all shows every field. The names follow the GitHub CLI’s JSON fields, such as title, author, state, reviewDecision, statusCheckRollup and mergeable; prtool fields lists all 46. Without --fields:

Command and hostDefault fields
view, GitHubtitle, author, state, isDraft, reviewDecision, baseRefName, headRefName, additions, deletions, changedFiles, url
list, GitHubnumber, title, author, state, reviewDecision, additions, deletions, changedFiles
view, GitLabtitle, author, state, isDraft, baseRefName, headRefName, mergeable, labels, url
list, GitLabtitle, number, author, state, mergeable, labels

A short --fields list makes each list row shorter to hear or to read on a braille line.

Limits

  • There is no JSON output. For structured data, call gh pr view --json or glab mr view --output json directly.
  • There is no --width option and no speech or braille layout. The drawn diff follows the terminal width.
  • list is a table of aligned columns. Each row is one line, but a screen reader reads the columns without their names. Use view for labelled fields.
  • File names in the drawn diff, --stat and --name-only, and hunk context, are bold even when colour is off, including in a pipe. Pipe through sed 's/\x1b\[[0-9;]*m//g' to strip it.
  • Actual screen-reader, braille-display and magnification use has not been measured.
  • prtool depends on gh and glab for authentication, networking and rate limits, and reports their errors as they are.

How it fits with the other tools

prtool works on its own, on an engineer’s machine or in a script. It reads the request; it does not review it. To walk a diff one change at a time, pipe the patch to rcdo:

prtool diff 14629 --repo cli/cli | rcdo diff-walk --summary-only

rcdo’s review and pr-manager commands check a pull request against policy. prtool shows you what the request says and changes. See accessible tooling for the other tools in this group.

Built from the public prtool repository (README.md, go.mod, main.go, internal/) at commit b90c369.