> ## Documentation Index
> Fetch the complete documentation index at: https://gtmsdk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PR review-thread utility

> Inspect and selectively resolve GitHub PR review threads with scripts/pr-review-threads.py, run entirely through a pinned Dagger container.

`scripts/pr-review-threads.py` replaces the improvised manual workflow of paginating `gh api graphql` for a pull request's review threads and hand-picking unresolved CodeRabbit comments to resolve. It always runs `gh` inside a pinned Dagger container — there is no host `gh` fallback, so it does not run in environments without a Dagger engine (for example, Conductor cloud sandboxes).

## Usage

```bash theme={"system"}
scripts/pr-review-threads.py inspect [--repo OWNER/REPO] [--pr NUMBER] \
    [--provider LOGIN] [--unresolved-only] [--format table|json]

scripts/pr-review-threads.py resolve --repo OWNER/REPO --pr NUMBER \
    --thread THREAD_ID [--thread THREAD_ID ...] [--allow-outdated] \
    [--format table|json]
```

`--repo`/`--pr` default to the current branch's associated PR (via `gh pr view`). `--provider coderabbitai` is a shorthand for the `coderabbitai[bot]` author login; any other value matches an exact `author.login`.

`GH_TOKEN` (or `GITHUB_TOKEN`, or `gh auth token` output) is required and is injected into the Dagger container only as a secret environment variable — never in command-line arguments, image layers, logs, or the script's own output.

## Safety model

* `inspect` is strictly read-only and never invokes the resolve mutation.
* `resolve` mutates only the thread IDs passed via `--thread`. It never guesses or resolves by path/body/provider.
* Validation is all-or-nothing: any unknown thread ID, or any outdated thread without `--allow-outdated`, refuses the entire request before any mutation runs. GitHub has no batch resolve mutation, so this does not make the mutation calls themselves atomic — if a later one fails after earlier ones succeeded, the command reports what it actually resolved and exits non-zero.
* Already-resolved thread IDs are reported as no-ops; no mutation call is issued for them.
* Exit codes: `0` success, `2` usage error, `3` auth/API/GraphQL failure, `4` refusal (unsafe/unknown/outdated mutation request).

## Implementation notes

Pagination is fully recursive across `reviewThreads`, `reviews`, top-level pull request comments, and each thread's own nested `comments` connection. The base container image is pinned (`ghcr.io/astral-sh/uv:0.11.29-python3.13-trixie-slim`), matching `scripts/webhooks-handlers-redeploy.py`'s `DAGGER_BASE_IMAGE`, for dependency-version consistency across the repo's Dagger pipelines.


## Related topics

- [Module boundaries](/contributing/module-boundaries.md)
- [Architecture](/concepts/architecture.md)
- [This week in gtm-sdk (week of July 13, 2026)](/changelog/2026-week-of-07-13.md)
- [CLI contract](/concepts/cli-contract.md)
- [Launch week — gtm-sdk goes public (July 13, 2026)](/changelog/2026-07-13.md)
