Metadata-Version: 2.4
Name: gh-llm
Version: 0.1.18
Summary: 🤖 CLI tooling for LLM-first GitHub reading and review workflows.
Keywords: github,cli,llm,code-review,pull-requests,issues
Author: Nyakku Shigure
Author-email: Nyakku Shigure <sigure.qaq@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Environment :: Console
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Programming Language :: Python :: Implementation :: CPython
Requires-Python: >=3.14
Project-URL: Homepage, https://github.com/ShigureLab/gh-llm
Project-URL: Documentation, https://github.com/ShigureLab/gh-llm
Project-URL: Repository, https://github.com/ShigureLab/gh-llm
Project-URL: Issues, https://github.com/ShigureLab/gh-llm/issues
Description-Content-Type: text/markdown

# gh-llm

Structured GitHub context for LLMs — read PRs, issues, and repos the way GitHub Web shows them, as LLM-friendly text with actionable commands.

<p align="center">
  <a href="https://python.org/" target="_blank"><img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/gh-llm?logo=python&style=flat-square"></a>
  <a href="https://pypi.org/project/gh-llm/" target="_blank"><img src="https://img.shields.io/pypi/v/gh-llm?style=flat-square" alt="pypi"></a>
  <a href="https://pypi.org/project/gh-llm/" target="_blank"><img alt="PyPI - Downloads" src="https://img.shields.io/pypi/dm/gh-llm?style=flat-square"></a>
  <a href="LICENSE"><img alt="LICENSE" src="https://img.shields.io/github/license/ShigureLab/gh-llm?style=flat-square"></a>
  <br/>
  <a href="https://github.com/astral-sh/uv"><img alt="uv" src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json&style=flat-square"></a>
  <a href="https://github.com/astral-sh/ruff"><img alt="ruff" src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json&style=flat-square"></a>
  <a href="https://gitmoji.dev"><img alt="Gitmoji" src="https://img.shields.io/badge/gitmoji-%20😜%20😍-FFDD67?style=flat-square"></a>
</p>

## Core Goal

`gh-llm` gives you (or your AI agent) the same context a human reviewer gets on GitHub Web — rendered as structured text with ready-to-run follow-up commands at every decision point.

## Key Ideas

- **Timeline-first rendering** — Comments, reviews, commits, labels, references, force-pushes, and state changes merge into one ordered stream that mirrors the GitHub Web experience.
- **Real cursor pagination** — Uses GitHub GraphQL `first/after` and `last/before` cursors, so page expansion always fetches real server-side data instead of slicing locally.
- **Progressive context loading** — Shows the first + last page first (high-signal summary), then expands hidden pages or events only on request.
- **Action-oriented output** — Places ready-to-run `gh` / `gh-llm` commands at decision points: expand, view detail, reply, resolve, review.
- **Stateless interaction model** — No fragile local session state between commands.

## Requirements

- Python `3.14+`
- `gh` installed and authenticated (`gh auth status`)

## Install

### As CLI (recommended)

```bash
uv tool install gh-llm
gh-llm --help
```

### As gh extension

```bash
gh extension install ShigureLab/gh-llm
gh llm --help
```

The extension entrypoint forwards to local repository path via `uv run --project <extension_repo_path> gh-llm ...`.
`gh llm ...` and `gh-llm ...` are equivalent command surfaces.

## Install Skill

If you want the reusable GitHub conversation skill, install it directly from this repo:

```bash
npx skills add https://github.com/ShigureLab/gh-llm --skill github-conversation
```

## Quick Start

### PR Reading

Read a PR's full timeline — metadata, comments, reviews, checks — with progressive expansion:

```bash
# Initial read: show first + last timeline pages with actionable hints
gh-llm pr view 77900 --repo PaddlePaddle/Paddle
gh llm pr view 77900 --repo PaddlePaddle/Paddle

# Later incremental read: reuse the previous frontmatter `fetched_at`
gh-llm pr view 77900 --repo PaddlePaddle/Paddle --after 2026-04-08T02:41:17Z

# Show selected regions only
gh-llm pr view 77900 --repo PaddlePaddle/Paddle --show timeline,checks

# Expand one hidden timeline page
gh-llm pr timeline-expand 2 --pr 77900 --repo PaddlePaddle/Paddle
gh-llm pr timeline-expand 2 --pr 77900 --repo PaddlePaddle/Paddle --after 2026-04-08T02:41:17Z

# Auto-expand folded content in default/timeline view
gh-llm pr view 77900 --repo PaddlePaddle/Paddle --expand resolved,minimized
gh-llm pr timeline-expand 2 --pr 77900 --repo PaddlePaddle/Paddle --expand all

# Auto-collapse noisy comment/review authors in timeline output
gh-llm pr view 77900 --repo PaddlePaddle/Paddle --auto-collapse-author PaddlePaddle-bot
gh-llm pr timeline-expand 2 --pr 77900 --repo PaddlePaddle/Paddle --auto-collapse-author PaddlePaddle-bot,other-bot

# Show full content for one comment node id
gh-llm pr comment-expand IC_xxx --pr 77900 --repo PaddlePaddle/Paddle

# Expand resolved review details in batch
gh-llm pr review-expand PRR_xxx,PRR_yyy --pr 77900 --repo PaddlePaddle/Paddle
# Expand only a conversation range (e.g. hidden middle part)
gh-llm pr review-expand PRR_xxx --threads 6-16 --pr 77900 --repo PaddlePaddle/Paddle

# Checks
gh-llm pr checks --pr 77900 --repo PaddlePaddle/Paddle
gh-llm pr checks --pr 77900 --repo PaddlePaddle/Paddle --all

# Native GitHub stacks (no gh-stack installation needed)
gh-llm pr view 825 --repo yutto-dev/yutto --show stack
gh-llm pr view 825 --repo yutto-dev/yutto --show stack,checks,mergeability

# Detect conflicted files on demand (for conflicted PRs)
gh-llm pr conflict-files --pr 77971 --repo PaddlePaddle/Paddle
```

Native stacks appear in the default PR overview with bottom-to-top ordering, the current layer, the target branch, and each member's draft, review, merge, and CI state. `--show meta` includes membership without loading the other members; `--show stack` loads their summaries without fetching their timelines or detailed checks.

Checks are paginated and tied to the PR head. Workflow names and run links distinguish same-named jobs; the display keeps the latest reported run per workflow and event. For stacks, required checks come from the stack target's classic branch protection and rulesets, with missing contexts shown as `EXPECTED`. Required checks pinned to an app must match that app; optional failures alone do not block a stack merge. If branch rules are inaccessible, the output reports that required-check coverage is incomplete. `pr checks --all` also shows historical head checks for closed and merged PRs.

Stack mergeability describes the unmerged layers from the bottom through the selected PR and their blockers, then links to GitHub's native stack merge controls. GitHub makes the final readiness decision. Diff and `review-start` remain scoped to the selected PR and its direct base; cumulative stack diffs are not included. Base branch changes appear in the timeline. Historical stack join/leave events are not reconstructed: the API does not reliably expose their historical stack IDs.

### PR Body Scaffold

Generate a PR body from the repo's template (or a default scaffold) with required sections pre-filled:

```bash
# Load the repo PR template (when present), append required sections, and write a body file
# The command also prints a ready-to-run `gh pr create --body-file ...` command.
gh-llm pr body-template --repo ShigureLab/watchfs --title 'feat: add watcher summary'

gh-llm pr body-template \
  --repo ShigureLab/watchfs \
  --requirements 'Motivation,Validation,Related Issues' \
  --output /tmp/pr_body.md
```

If the repo has no PR template, `gh-llm` falls back to a simple editable scaffold.
The bundled `skills/github-conversation/SKILL.md` also documents this workflow for skill users.

### Issue Reading

Issue reading works the same way as PR reading — timeline view with progressive expansion:

```bash
gh-llm issue view 77924 --repo PaddlePaddle/Paddle
gh-llm issue view 77924 --repo PaddlePaddle/Paddle --after 2026-04-08T02:41:17Z
gh-llm issue timeline-expand 2 --issue 77924 --repo PaddlePaddle/Paddle
gh-llm issue timeline-expand 2 --issue 77924 --repo PaddlePaddle/Paddle --after 2026-04-08T02:41:17Z
gh-llm issue view 77924 --repo PaddlePaddle/Paddle --auto-collapse-author PaddlePaddle-bot
gh-llm issue comment-expand IC_xxx --issue 77924 --repo PaddlePaddle/Paddle
gh-llm issue view 77924 --repo PaddlePaddle/Paddle --expand minimized,details
gh-llm issue view 77924 --repo PaddlePaddle/Paddle --show meta,description
```

For incremental follow-ups, copy the previous output's `fetched_at` value into `--after <fetched_at>`. `--before` is also available when you want to inspect only older timeline slices.

When `--show` does not include `timeline` (for example `--show meta`, `--show summary`, or `--show actions`), both `pr view` and `issue view` stay on the lightweight metadata path and skip timeline bootstrap.

Use `--show` to choose which output sections to render. Use `--expand` to automatically open folded content within those sections.

Use `--auto-collapse-author <login>` on `pr view`, `pr timeline-expand`, `issue view`, or `issue timeline-expand` to replace selected authors' timeline comments/reviews with a compact placeholder that includes author, node/review id, and body size. Values are case-insensitive, may start with `@`, and support comma-separated or repeated flags. Without this option, output is unchanged. To view full content, run the emitted `comment-expand` / `review-expand` command, or rerun without `--auto-collapse-author`.

`--expand` values:

- PR: `resolved`, `minimized`, `details`, `all`
- Issue: `minimized`, `details`, `all`
- Supports comma-separated values and repeated flags.

`--show` values:

- PR: `meta`, `description`, `timeline`, `checks`, `actions`, `mergeability`, `stack`, `all`
- Issue: `meta`, `description`, `timeline`, `actions`, `all`
- Supports comma-separated values and repeated flags.
- `summary` is supported as an alias for `meta,description`.

### Comment / Thread Actions

Edit comments, reply to review threads, and resolve/unresolve threads directly from the CLI:

```bash
# Edit comment
gh-llm pr comment-edit IC_xxx --body '<new_body>' --pr 77900 --repo PaddlePaddle/Paddle
gh-llm pr comment-edit IC_xxx --body-file edit.md --pr 77900 --repo PaddlePaddle/Paddle
gh-llm issue comment-edit IC_xxx --body '<new_body>' --issue 77924 --repo PaddlePaddle/Paddle
gh-llm issue comment-edit IC_xxx --body-file edit.md --issue 77924 --repo PaddlePaddle/Paddle

# Reply / resolve / unresolve review thread
gh-llm pr thread-reply PRRT_xxx --body '<reply>' --pr 77900 --repo PaddlePaddle/Paddle
gh-llm pr thread-reply PRRT_xxx --body-file reply.md --pr 77900 --repo PaddlePaddle/Paddle
cat reply.md | gh-llm pr thread-reply PRRT_xxx --body-file - --pr 77900 --repo PaddlePaddle/Paddle
gh-llm pr thread-resolve PRRT_xxx --pr 77900 --repo PaddlePaddle/Paddle
gh-llm pr thread-unresolve PRRT_xxx --pr 77900 --repo PaddlePaddle/Paddle
```

### Environment Diagnosis

Verify your setup — `doctor` checks `gh` auth, connectivity, and proxy configuration:

```bash
gh-llm doctor
gh llm doctor
```

`doctor` prints the current entrypoint, resolved executable paths, `gh` / `gh-llm` versions,
active-host `gh auth status`, a REST probe, a minimal GraphQL probe, and proxy-related environment variables.
If `gh auth status` is noisy but both API probes succeed, `doctor` reports that auth check as a warning instead
of failing the whole diagnosis.

When `gh-llm` hits transport errors such as GraphQL `EOF` / timeout failures, the CLI now reports the
retry count and suggests concrete follow-up probes such as `gh api user`,
`gh api graphql -f query='query{viewer{login}}'`, and `gh-llm doctor`.

## PR Review Workflow

A complete code review in four steps — start from diff hunks, add inline comments or suggestions, then submit:

### 1) Start from diff hunks

```bash
gh-llm pr review-start --pr 77938 --repo PaddlePaddle/Paddle

# Large PRs: load the next changed-file page
gh-llm pr review-start --pr 78255 --repo PaddlePaddle/Paddle --page 2 --page-size 5

# Jump to an absolute changed-file range directly
gh-llm pr review-start --pr 78255 --repo PaddlePaddle/Paddle --files 6-12

# Add extra unchanged context around each hunk
gh-llm pr review-start --pr 77938 --repo PaddlePaddle/Paddle --context-lines 3

# Focus one changed file directly
gh-llm pr review-start --pr 78255 --repo PaddlePaddle/Paddle --path 'paddle/phi/api/include/compat/ATen/core/TensorBody.h'

# Show only selected hunks inside that file
gh-llm pr review-start --pr 78255 --repo PaddlePaddle/Paddle --path 'TensorBody.h' --hunks 2-3

# Reuse a pinned head snapshot when loading another page
gh-llm pr review-start --pr 78255 --repo PaddlePaddle/Paddle --page 2 --page-size 5 --head <head_sha>
```

It prints changed-file page summary, existing review-thread summaries with lightweight comment previews inline on matching diff lines when possible, per-hunk commentable LEFT/RIGHT line ranges, numbered diff lines, and ready-to-run review-comment commands.
Generated follow-up commands reuse `--head <head_sha>` automatically so pagination and inline review commands stay on the same PR snapshot; stale snapshots are rejected with a refresh hint.
Use `--context-lines <n>` when the GitHub patch hunk is too tight and you need a small amount of extra unchanged code around it.

### 2) Add inline comment

```bash
gh-llm pr review-comment \
  --path 'paddle/phi/api/include/compat/torch/library.h' \
  --line 106 \
  --side RIGHT \
  --body 'Please add a regression test for duplicate keyword arguments.' \
  --pr 77938 --repo PaddlePaddle/Paddle

gh-llm pr review-comment \
  --path 'paddle/phi/api/include/compat/torch/library.h' \
  --line 106 \
  --side RIGHT \
  --body-file review-comment.md \
  --pr 77938 --repo PaddlePaddle/Paddle
```

### 3) Add inline suggestion

When the replacement is known and verified, prefer an applicable suggestion over describing the code change in prose. Put the explanation and a fenced `suggestion` block in one complete Markdown body, then send it with `review-comment`. The body is sent as written.

````bash
cat <<'EOF' > /tmp/review-comment.md
Use the new API to handle this case.

```suggestion
new_api_call()
```
EOF

gh-llm pr review-comment \
  --path 'path/to/file' \
  --line 123 \
  --side RIGHT \
  --body-file /tmp/review-comment.md \
  --pr 77938 --repo PaddlePaddle/Paddle
````

For a replacement spanning multiple original lines, add `--start-line <first_line>` and use `--line <last_line>` for the continuous range. Include the full replacement for that range in the suggestion block. Reuse `--head <head_sha>` from `review-start` to reject stale review locations. A successful suggestion comment reports `status: commented` and returns the thread/comment IDs.

To reply to an existing suggestion, read its thread first and reply in the same thread:

```bash
gh-llm pr thread-expand <PRRT_id> --pr <pr> --repo <owner/repo>
gh-llm pr thread-reply <PRRT_id> --body-file reply.md --pr <pr> --repo <owner/repo>
```

State whether the suggestion was adopted, adapted, or declined, with the relevant commit or validation. Wait for `status: replied` before treating the reply as sent.

### 4) Submit review

```bash
gh-llm pr review-submit \
  --event COMMENT \
  --body 'Overall feedback...' \
  --pr 77938 --repo PaddlePaddle/Paddle

gh-llm pr review-submit \
  --event REQUEST_CHANGES \
  --body-file review.md \
  --pr 77938 --repo PaddlePaddle/Paddle
```

Pick the strongest explicit review outcome the evidence supports:

- `APPROVE`: ready to merge from your side
- `REQUEST_CHANGES`: blocking issues remain
- `COMMENT`: non-blocking notes or intermediate status only

`pr comment-edit`, `issue comment-edit`, `thread-reply`, `review-comment`, and `review-submit` all support `--body-file -` to read multi-line text from standard input.

## Multiline body safety

GitHub stores body text exactly as sent. If you pass literal escape sequences such as `\n\n` inside `--body`, those backslashes may be stored literally and show up in the final review/comment.

Use `--body` for short one-line text. Use `--body-file` for quotes, multiple paragraphs, bullet lists, and code fences:

```bash
cat <<'EOF' > /tmp/review.md
> Reviewer point

Fixed in `python/demo.py:42`.
Validation: `pytest test/demo_test.py -q`
EOF

gh-llm pr thread-reply PRRT_xxx --body-file /tmp/review.md --pr 77938 --repo PaddlePaddle/Paddle
gh-llm pr review-submit --event COMMENT --body-file /tmp/review.md --pr 77938 --repo PaddlePaddle/Paddle
gh pr comment 77938 --repo PaddlePaddle/Paddle --body-file /tmp/review.md
```

Submit behavior:

- If you already have a pending review on this PR, `review-submit` submits that pending review.
- Otherwise, it creates and submits a new review.

This supports the normal flow where one review contains multiple inline comments.

## Render Conventions

All output follows consistent formatting rules so both humans and LLMs can parse it reliably:

- **Metadata** is rendered as YAML-style frontmatter at the top of PR/issue views.
- Frontmatter includes `fetched_at`, so the next incremental read can use `--after <fetched_at>`.
- When timeline filtering is active, frontmatter also includes `timeline_after` / `timeline_before` and filtered vs unfiltered event counts.
- **Description** is wrapped in `<description>...</description>` tags.
- **Comment bodies** use `<comment>...</comment>` tags to avoid markdown fence ambiguity with code blocks inside comments.
- **Hidden timeline sections** are separated by `---` dividers and include ready-to-run expand commands to load the omitted content.

## Development

```bash
uv run ruff check
uv run ty check --error-on-warning src/gh_llm tests
uv run pytest -q
```

## License

MIT
