|
| 1 | +# Tasks: PR/MR Review from URL |
| 2 | + |
| 3 | +**Input**: Design documents from `/specs/20260329-233618-pr-review/` |
| 4 | +**Prerequisites**: spec.md ✓ |
| 5 | + |
| 6 | +**Structure**: All code lives in `app.py` (single-file architecture per constitution). |
| 7 | + |
| 8 | +--- |
| 9 | + |
| 10 | +## Phase 1: Core Types & URL Resolution |
| 11 | + |
| 12 | +- [X] T001 Add `PRMetadata` NamedTuple to Types section of `app.py` — fields: `provider`, `owner`, `repo`, `number`, `title`, `state`, `author`, `base`, `head`, `url`, `head_clone_url`, `head_owner`, `description` |
| 13 | +- [X] T002 Implement `_resolve_pr_url(url) -> PRMetadata` in `app.py` — parses GitHub PR URLs (`github.com/.../pull/N`) and GitLab MR URLs (`gitlab.com/.../merge_requests/N`); calls provider REST API to fetch base/head branch names, title, state, author, description; raises `ValueError` for unsupported URL formats |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## Phase 2: CLI `--pr` Flag |
| 18 | + |
| 19 | +- [X] T003 Implement `_add_fork_remote(tmpdir, fork_url, branch)` helper in `app.py` — adds `pr-head` remote pointing at the fork and fetches the given branch with `--filter=blob:none` |
| 20 | +- [X] T004 Implement `_pr_review(url, provider_key, depth)` async function in `app.py` — resolves PR metadata, clones base repo, adds fork remote for cross-fork PRs, calls `compare_branches(base, head_ref)`, writes export via `_write_export(result, pr_meta=pr)`, prints summary to stdout |
| 21 | +- [X] T005 Add `--pr URL` argument to `main()` argparse in `app.py` — takes priority over `--compare`; `owner/repo` positional arg optional (inferred from URL) |
| 22 | +- [X] T006 Update `_write_export()` to accept optional `pr_meta` — when present: use `compare-{owner}-{repo}-pr{N}-{YYYYMMDD}.txt` filename; prepend PR metadata header (URL, title, author, state, description) before diff sections |
| 23 | + |
| 24 | +--- |
| 25 | + |
| 26 | +## Phase 3: TUI Integration |
| 27 | + |
| 28 | +- [X] T007 Pass `owner`, `repo`, `provider` to `CompareScreen.__init__()` from `action_compare()` in `CommitExplorer` |
| 29 | +- [X] T008 Add PR/MR number input row to `CompareScreen.compose()` — `Input` with placeholder "PR/MR number (e.g. 123)" + "Fill branches" `Button`; placed above existing branch inputs |
| 30 | +- [X] T009 Implement `_build_pr_url(number)` method on `CompareScreen` — constructs full GitHub/GitLab URL from loaded repo context; raises `ValueError` if repo not loaded or provider unsupported |
| 31 | +- [X] T010 Implement `_run_pr_resolve()` `@work` method on `CompareScreen` — resolves PR URL, adds fork remote if cross-fork, auto-fills base/target inputs, triggers `_run_comparison()`; stores `pr_meta` in `self._last_pr` |
| 32 | +- [X] T011 Update `_render_comparison()` to show PR header when `self._last_pr` is set — display title, author, state, and up to 20 lines of description (truncated with "… see export" notice) |
| 33 | +- [X] T012 Update `on_export_pressed()` to pass `pr_meta=self._last_pr` to `_write_export()` so export filename includes PR number |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## Phase 4: Cross-Fork PR Support |
| 38 | + |
| 39 | +- [X] T013 Detect cross-fork PRs in `_pr_review()` — compare `pr.head_owner` vs `pr.owner`; if different, call `_add_fork_remote()` and set `head_ref = "pr-head/<branch>"` |
| 40 | +- [X] T014 Detect cross-fork PRs in `CompareScreen._run_pr_resolve()` — same logic; set target input to `pr-head/<branch>` so `_run_comparison()` uses the correct ref |
| 41 | +- [X] T015 Update `compare_branches()` ref resolution — handle pre-qualified refs (`pr-head/...`) without adding `origin/` prefix; update blob fetch to use correct remote per ref |
| 42 | + |
| 43 | +--- |
| 44 | + |
| 45 | +## Validation |
| 46 | + |
| 47 | +- [X] T016 CLI: tested with `cex --pr https://github.com/anthropics/claude-code/pull/40594` (cross-fork PR) — 7 files changed, correct diff and commit log in export |
| 48 | +- [X] T017 TUI: tested with PR number input `40586` on `anthropics/claude-code` — base/target auto-filled, comparison runs, PR title shown in results |
0 commit comments