PR review fetcher
Fetch only — capture the review feedback left on a pull request; never fix code, reply, or
judge the comments. Output is a self-contained .PR-REVIEW.md a fresh session can pick up and act
on (e.g. via /refine-pr-review).
Source & access
Identify the platform from the PR URL (host shape) and fetch through the matching MCP server or
CLI — e.g. GitHub MCP / gh for GitHub PRs, Azure DevOps MCP for ADO pull requests. Use
whichever equivalent tools are connected; tool name prefixes vary by config. If the input is
ambiguous, or no matching MCP/CLI is available, ask the user / stop — don't guess.
Golden rule: never assume — ask
Every uncertainty is confirmed with the user before proceeding: a thread's resolved status, the
planning directory, the slug, anything ambiguous in between. A plausible guess is a question, not
an answer.
Your task
- Resolve the input. Accept a full PR URL; extract repo/project and PR id. If unrecognizable,
ask.
- Fetch the PR metadata — title, description, source/target branch, state, author, linked
ticket/work item — and all feedback:
- inline review threads (file, line, code context, full reply chain);
- top-level review verdicts (approve / request changes / …) with their summary text;
- general conversation comments;
- bot comments (CI, linters, coverage, …) — captured too, but grouped separately from human
feedback.
- Determine each thread's status (see Status flags).
- Decide the output directory — the planning directory of the task the PR belongs to,
following the project's/user's convention for where plans live (default:
.agents/plans/).
Guess the task's existing home from PR context (linked ticket id, branch name, PR title) — its
<id>-<slug>/ subdirectory, or the shared parent/group directory holding its
<id>-<slug>.TICKET.md when the ticket lives flat there — and confirm the guess with the
user; when not sure, always ask. If no matching exists, propose a new <id>-<slug> (ticket id
prefix when bound to one, kebab-case slug from the PR title), confirm, and create it.
- Pick the file name —
<slug>.PR-REVIEW.md, where <slug> is the planning directory name —
in a shared directory, the ticket's own <id>-<slug> instead (e.g.
1234-some-task.PR-REVIEW.md). If it already exists and this is a new review round, write
<slug>.PR-REVIEW-2.md, -3, … — never overwrite; history per round is kept on purpose.
- Write the document (see structure below).
- Print the result — project-relative paths and the next-step line.
Status flags
Capture every comment, resolved or not, with its state from the platform's own signal (e.g.
GitHub thread resolution, ADO thread status):
- Open / active → actionable; no flag needed.
- Resolved (closed, fixed, won't fix, …) → keep it, marked resolved, with the platform's
original status verbatim —
wontFix is resolved but carries different intent than fixed.
- Outdated (anchored to code later commits changed) → distinct outdated flag, never merged
into resolved: the code moved, but the concern may still be valid — say so in the document.
- Unclear — the platform gives no clear signal, or the thread reads ambiguous (e.g. a reply
says "done" but the thread is still open) → ask the user how to mark it; never decide alone.
Document structure
Must stand on its own: a fresh session with no access to the PR must be able to locate every spot
in the code and understand every piece of feedback without re-fetching.
# PR review: <title>
> **Source** [<PR id>](<url>)
> **Branch** <source> → <target>
> **State** {open/merged/…}
> **Author** {display name}
> **Linked ticket** [<id>](<url>) — omit if none
> **Fetched** {today YYYY-MM-DD}
## Review verdicts — one per reviewer: verdict + summary text
## Inline threads — one ### per thread: `path:line`, quoted code context/diff hunk,
comments oldest first as <author> — <date>, status flag
## General comments — non-inline human conversation, oldest first
## Bot comments — automated feedback, grouped by bot
Omit empty sections. Quote file paths, code, identifiers, and user-facing strings verbatim —
never alter or translate them.
Boundaries
- The PR stays untouched — fetching is read-only: no replies, no resolving threads, no votes,
approvals, or edits.
- Do not fix, analyze, or triage the feedback — capture and flag only.
- The only files you create: the
.PR-REVIEW.md (and its planning directory if new).
Next step
State clearly when done, using project-relative paths. List any thread whose status needed a
user decision and how it was marked. Then hand off the next phase as a
single copy-pasteable launch command — session name and prompt combined, so one paste starts the
session. Use the launch syntax of the agent tool in use (vendor-agnostic — claude below is only
the example), naming the session refine-pr-<slug>:
claude --name refine-pr-<slug> "/refine-pr-review <output-dir>/<slug>.PR-REVIEW.md"
Then offer the alternative — clearing the current session instead (vendor-agnostic — /clear below
is only the example; use the clear command of the agent tool in use):
OR /clear and run:
/refine-pr-review <output-dir>/<slug>.PR-REVIEW.md
1---2name: fetch-pr-review3description: Fetch all reviewer comments from a pull request URL (GitHub, Azure DevOps, …) and save them as a self-contained markdown PR-REVIEW file in the task's planning directory. Fetch only — no fixing or replying.4license: MIT5---67# PR review fetcher89**Fetch only** — capture the review feedback left on a pull request; never fix code, reply, or10judge the comments. Output is a self-contained `.PR-REVIEW.md` a fresh session can pick up and act11on (e.g. via `/refine-pr-review`).1213## Source & access1415Identify the platform from the PR URL (host shape) and fetch through the matching MCP server or16CLI — e.g. **GitHub MCP / `gh`** for GitHub PRs, **Azure DevOps MCP** for ADO pull requests. Use17whichever equivalent tools are connected; tool name prefixes vary by config. If the input is18ambiguous, or no matching MCP/CLI is available, ask the user / stop — don't guess.1920## Golden rule: never assume — ask2122Every uncertainty is confirmed with the user before proceeding: a thread's resolved status, the23planning directory, the slug, anything ambiguous in between. A plausible guess is a question, not24an answer.2526## Your task27281. **Resolve the input.** Accept a full PR URL; extract repo/project and PR id. If unrecognizable,29 ask.302. **Fetch the PR metadata** — title, description, source/target branch, state, author, linked31 ticket/work item — and **all feedback**:32 - inline review threads (file, line, code context, full reply chain);33 - top-level review verdicts (approve / request changes / …) with their summary text;34 - general conversation comments;35 - bot comments (CI, linters, coverage, …) — captured too, but grouped separately from human36 feedback.373. **Determine each thread's status** (see Status flags).384. **Decide the output directory** — the planning directory of the task the PR belongs to,39 following the project's/user's convention for where plans live (default: `.agents/plans/`).40 Guess the task's existing home from PR context (linked ticket id, branch name, PR title) — its41 `<id>-<slug>/` subdirectory, or the shared parent/group directory holding its42 `<id>-<slug>.TICKET.md` when the ticket lives flat there — and **confirm the guess with the43 user**; when not sure, always ask. If no matching exists, propose a new `<id>-<slug>` (ticket id44 prefix when bound to one, kebab-case slug from the PR title), confirm, and create it.455. **Pick the file name** — `<slug>.PR-REVIEW.md`, where `<slug>` is the planning directory name —46 in a shared directory, the ticket's own `<id>-<slug>` instead (e.g.47 `1234-some-task.PR-REVIEW.md`). If it already exists and this is a new review round, write48 `<slug>.PR-REVIEW-2.md`, `-3`, … — **never overwrite**; history per round is kept on purpose.496. **Write the document** (see structure below).507. **Print the result** — project-relative paths and the next-step line.5152## Status flags5354Capture **every** comment, resolved or not, with its state from the platform's own signal (e.g.55GitHub thread resolution, ADO thread status):5657- **Open / active** → actionable; no flag needed.58- **Resolved** (closed, fixed, won't fix, …) → keep it, marked **resolved**, with the platform's59 original status verbatim — `wontFix` is resolved but carries different intent than `fixed`.60- **Outdated** (anchored to code later commits changed) → distinct **outdated** flag, never merged61 into resolved: the code moved, but **the concern may still be valid** — say so in the document.62- **Unclear** — the platform gives no clear signal, or the thread reads ambiguous (e.g. a reply63 says "done" but the thread is still open) → **ask the user** how to mark it; never decide alone.6465## Document structure6667Must stand on its own: a fresh session with no access to the PR must be able to locate every spot68in the code and understand every piece of feedback without re-fetching.6970```markdown71# PR review: <title>7273> **Source** [<PR id>](<url>)74> **Branch** <source> → <target>75> **State** {open/merged/…}76> **Author** {display name}77> **Linked ticket** [<id>](<url>) — omit if none78> **Fetched** {today YYYY-MM-DD}7980## Review verdicts — one per reviewer: verdict + summary text81## Inline threads — one ### per thread: `path:line`, quoted code context/diff hunk,82 comments oldest first as <author> — <date>, status flag83## General comments — non-inline human conversation, oldest first84## Bot comments — automated feedback, grouped by bot85```8687Omit empty sections. Quote file paths, code, identifiers, and user-facing strings **verbatim** —88never alter or translate them.8990## Boundaries9192- The PR stays untouched — fetching is **read-only**: no replies, no resolving threads, no votes,93 approvals, or edits.94- **Do not** fix, analyze, or triage the feedback — capture and flag only.95- The only files you create: the `.PR-REVIEW.md` (and its planning directory if new).9697## Next step9899State clearly when done, using **project-relative paths**. List any thread whose status needed a100user decision and how it was marked. Then hand off the next phase as a101**single copy-pasteable launch command** — session name and prompt combined, so one paste starts the102session. Use the launch syntax of the agent tool in use (vendor-agnostic — `claude` below is only103the example), naming the session `refine-pr-<slug>`:104105```106claude --name refine-pr-<slug> "/refine-pr-review <output-dir>/<slug>.PR-REVIEW.md"107```108109Then offer the alternative — clearing the current session instead (vendor-agnostic — `/clear` below110is only the example; use the clear command of the agent tool in use):111112OR /clear and run:113114```115/refine-pr-review <output-dir>/<slug>.PR-REVIEW.md116```