quinjet 0.0.9

A fast, live, keyboard-first Git source-control interface for the terminal
# `quinjet pr view`

Prints one pull request's metadata and its description.

Usage:

```bash
quinjet pr view <number> [--repo <owner/name>] [--refresh] [-C <DIR>] [--json]
```

Arguments:

| Name | Type / values | Default | What it does |
| --- | --- | --- | --- |
| `<NUMBER>` | unsigned integer | required | The pull-request number. `0` is rejected at runtime, a non-integer at parse time. |

Options:

| Name | Type / values | Default | What it does |
| --- | --- | --- | --- |
| `--repo <OWNER/NAME>` | string | unset | Chooses which discovered repository the number belongs to. Matched case-insensitively against `owner/name`, or against the tail of the repository URL. |
| `--refresh` | flag | off | Asks GitHub again instead of answering from the five-minute metadata cache. |
| `-C, --path <DIR>` | path | `.` | The repository to run against. Global. |
| `--json` | flag | off | Prints one JSON object on stdout instead of the text block. Global. |
| `-h, --help` | flag | off | Prints this verb's help on stdout and exits 0. |

This is the lookup and nothing else, so it is the cheapest way to check that
`gh`, the remotes and the number all line up before running a verb that also has
to fetch commits. Underneath it runs exactly one command:

```text
gh pr view <number> --repo <canonical-url> \
  --json number,title,body,author,state,isDraft,createdAt,updatedAt,url,baseRefName,baseRefOid,headRefName,headRefOid,headRepository,isCrossRepository,additions,deletions,changedFiles \
  --jq '[(.number|tostring), .title, (.body // ""), (.author.login // "ghost"), ...] | @tsv'
```

The answer is one tab-separated line of 18 fields, cached under
`pull-request-v3\n<repository url>\n<number>` for five minutes. Tabs, newlines,
carriage returns and backslashes inside the body arrive escaped and are put back
before the record is parsed, which is what lets a multi-line description survive
a one-line format.

The state line is a small piece of interpretation rather than a raw field. A
draft prints `DRAFT` in place of its real state, so `OPEN`, `MERGED`, `CLOSED`
and `DRAFT` are the four things that line can say. `Source` and `Destination`
are labels, not refs: a same-repository pull request shows the bare head branch,
a fork shows `owner/name:branch`, a GitHub Enterprise fork shows
`host/owner/name:branch`, and a pull request whose fork has been deleted shows
`deleted fork:<branch>`. An author GitHub no longer knows prints as `ghost`.

Warnings from repository discovery and from a stale cache fall out on stderr
before the block is written, so a redirect keeps stdout clean:

```console
$ quinjet pr view 8 > pr.txt
warning: GitHub is unavailable; showing stale cached metadata for #8
```

The description is printed verbatim after a blank line, with trailing whitespace
removed and nothing else done to it. Markdown is not rendered, links are not
shortened, and a body over 256 KiB is cut at a character boundary and ends in
`…`. A pull request with an empty body prints no blank line and no body at all.

`--json` shape, one object. `baseOid` and `headOid` are the commits
[`quinjet pr files`](./files.md) and [`quinjet pr diff`](./diff.md) work from,
`headRepository` is `null` when the fork has been deleted, and `headRemotes`
lists the local remote names that point at the head repository, which is empty
for a fork you have not added as a remote:

```json
{
  "number": 8,
  "title": "Read pull requests, watch their checks, and index diffs up front",
  "description": "Adds a pull-request pane holding the description, conversation and check logs, keeps it live, and resolves every changed file's line counts while the index is built.",
  "author": "pulkitxm",
  "state": "MERGED",
  "isDraft": false,
  "createdAt": "2026-08-14T19:51:15Z",
  "updatedAt": "2026-08-15T13:19:57Z",
  "url": "https://github.com/pulkitxm/quinjet/pull/8",
  "baseRef": "main",
  "baseOid": "5451c8cc4376a6ea6d8f54043aef5749e262f193",
  "headRef": "feat/pr-conversation-live-checks",
  "headOid": "df8b3a85ed92b0b1b8f11daf2e67ce0431a22d44",
  "baseRepository": {
    "nameWithOwner": "pulkitxm/quinjet",
    "url": "https://github.com/pulkitxm/quinjet",
    "remotes": ["origin"]
  },
  "headRepository": "pulkitxm/quinjet",
  "headRemotes": ["origin"],
  "isCrossRepository": false,
  "additions": 6284,
  "deletions": 602,
  "changedFiles": 14
}
```

Note that `state` in JSON is the real state, upper-cased, and `isDraft` is
separate. Only the text form collapses the two into `DRAFT`. `updatedAt` is the
stamp [`quinjet pr conversation`](./conversation.md) keys its cache on, so it
moves whenever anything at all happens in the thread.

Examples:

```bash
quinjet pr view 8
quinjet pr view 8 --json
quinjet pr view 8 --refresh
quinjet pr view 8 --repo pulkitxm/quinjet
quinjet pr view 8 -C ~/code/quinjet --json
```

```console
$ quinjet pr view 8
#8  Read pull requests, watch their checks, and index diffs up front
MERGED · @pulkitxm · opened 2026-08-14T19:51:15Z · updated 2026-08-15T13:19:57Z
Source       feat/pr-conversation-live-checks
Destination  pulkitxm/quinjet:main
Changes      14 files, +6284 -602
URL          https://github.com/pulkitxm/quinjet/pull/8

Adds a pull-request pane holding the description, conversation and check logs, keeps it live, and resolves every changed file's line counts while the index is built.
```

```console
$ quinjet pr view 8 --repo bogus/thing
error: no remote of this checkout points at `bogus/thing`
hint: run `quinjet repos` for the repositories it can see
```

```console
$ quinjet pr view 99999
error: unable to load pull request: GraphQL: Could not resolve to a PullRequest with the number of 99999. (repository.pullRequest)
```

The first of those exits 3, because a name was wrong. The second exits 1,
because `gh` was asked a sensible question and refused it.

## Where to go next

- [`quinjet pr`]./README.md, the rest of this group and its shared lookup
- [`quinjet pr files`]./files.md for what the pull request changes
- [All `quinjet` commands]../README.md