Skip to content

Commit c1f79f7

Browse files
committed
feat: PR review feedback helper (gh) and workflow docs
Made-with: Cursor
1 parent 03b4b40 commit c1f79f7

6 files changed

Lines changed: 764 additions & 0 deletions

File tree

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ GITHUB_TOKEN=
2424

2525
# Discovery, filters, and agent model are fixed in src/orchestrator.py (top-level constants).
2626

27+
# Optional: output file for `python pr_review.py` when --output is omitted (PR review follow-up).
28+
# IYNX_PR_REVIEW_FEEDBACK_PATH=
29+
2730
# Optional: append-only JSON Lines log for supervising agents (see README). Empty or 0 disables.
2831
# IYNX_PROGRESS_JSONL=.iynx-run-progress.jsonl
2932

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,30 @@ Use **`IYNX_PR_LABEL`** when running the agent so new PRs get the same label and
155155

156156
**Exit codes:** `0` success; `1` config/usage; `2` GitHub HTTP/network error after retries.
157157

158+
### PR review follow-up (GitHub)
159+
160+
After maintainers comment on an open PR, dump review threads into a **local markdown file** for an agent (or you) to implement fixes. Uses **`gh` only** (no direct GitHub REST in this tool). Install and authenticate [GitHub CLI](https://cli.github.com/) on the host.
161+
162+
**Default output:** `<contribution-repo>/.iynx/pr-review-feedback.md` — only if that path is **gitignored** in the target repo; otherwise pass **`--output`** or set **`IYNX_PR_REVIEW_FEEDBACK_PATH`**. **Do not commit** that file.
163+
164+
```bash
165+
# From inside the contribution clone (branch can be set with gh pr checkout)
166+
cd workspace/owner-repo
167+
python ../pr_review.py https://github.com/owner/repo/pull/42
168+
169+
# Or explicit repo + number (from any cwd; use --output if not in a git repo)
170+
python pr_review.py --repo owner/repo --pr 42 -o /tmp/pr-review-feedback.md
171+
172+
# PowerShell example with explicit output
173+
python pr_review.py "https://github.com/owner/repo/pull/42" --output "$env:TEMP\pr-review-feedback.md"
174+
```
175+
176+
**Clone / checkout (normalize first):** from the contribution repo, run `git fetch` and `gh pr checkout <N>` (same PR as your branch). If you have no clone yet, clone the **head** repository from `gh pr view <url> --json headRepository,baseRepository`, add `upstream` when the PR is from a fork, then `gh pr checkout`.
177+
178+
**Exit codes:** `0` file written; `1` usage or local validation (e.g. default path not gitignored); `2` `gh`/GitHub error.
179+
180+
See `skills/issue-fix-workflow.md` § PR review follow-up and `docs/superpowers/specs/2026-03-24-pr-review-followup-design.md`.
181+
158182
## Environment Variables
159183

160184
| Variable | Required | Description |
@@ -166,6 +190,7 @@ Use **`IYNX_PR_LABEL`** when running the agent so new PRs get the same label and
166190
| `IYNX_STATS_NO_LABEL` | No | If `1`/`true`, same as `python stats.py --no-label` (author + branch only; no label in search) |
167191
| `IYNX_STATS_BRANCH_REGEX` | No | Override branch regex for `stats.py` (default matches `fix/issue-<n>`) |
168192
| `IYNX_STATS_AUTHOR` | No | GitHub login for `stats.py` (default: token’s user) |
193+
| `IYNX_PR_REVIEW_FEEDBACK_PATH` | No | Output path for `python pr_review.py` when `--output` is omitted (same effect as `--output`; use to write without a local clone). For the default `.iynx/pr-review-feedback.md` path, you still need a repo root and a gitignored target unless you set this to a path outside the repo |
169194
| `IYNX_PROGRESS_JSONL` | No | Path to JSONL progress file; empty/`0`/`false` disables the file |
170195
| `IYNX_DOCKER_TTY` | No | If `1` (default), `docker run -t` for streamed steps so Cursor CLI output is line-buffered to the host; set `0` if `-t` fails (e.g. some CI) |
171196
| `IYNX_DOCKER_TRACE` | No | If `1` (default), every Docker shell step prints `[iynx-docker]` timestamp lines (clone, bootstrap, `cursor-agent`, verify, PR) so `docker logs` / host `[docker]` lines show clear phases; set `0` to silence |
@@ -194,8 +219,10 @@ iynx/
194219
│ ├── bootstrap.py # Generate .cursor-agent per repo
195220
│ ├── workflow_progress.py # JSONL progress for agents
196221
│ ├── pr_stats.py # GitHub PR stats CLI (label + branch filter)
222+
│ ├── pr_review_followup.py # PR review → markdown (`gh` only)
197223
│ └── pr.py # Fork + push + gh pr create
198224
├── stats.py # Entry: PR statistics (`python stats.py`)
225+
├── pr_review.py # Entry: PR review feedback file (`python pr_review.py`)
199226
├── skills/
200227
│ └── issue-fix-workflow.md
201228
├── tests/ # pytest (discovery + GitHub checks)

pr_review.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Write PR review feedback to markdown (gh CLI only).
4+
5+
Usage:
6+
python pr_review.py https://github.com/owner/repo/pull/42
7+
python pr_review.py owner/repo#42
8+
python pr_review.py --repo owner/repo --pr 42
9+
python pr_review.py 42 --repo owner/repo
10+
"""
11+
12+
import os
13+
import sys
14+
15+
_ROOT = os.path.dirname(os.path.abspath(__file__))
16+
17+
18+
def _ensure_src_on_path() -> None:
19+
src = os.path.join(_ROOT, "src")
20+
if src not in sys.path:
21+
sys.path.insert(0, src)
22+
23+
24+
if __name__ == "__main__":
25+
import run as run_module
26+
27+
run_module.load_dotenv_if_present(_ROOT)
28+
_ensure_src_on_path()
29+
from pr_review_followup import main
30+
31+
raise SystemExit(main())

skills/issue-fix-workflow.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,68 @@ Check `CONTRIBUTING.md`, `README.md`, or CI config for the actual commands.
9898
- **Disclaimer**: Mention AI involvement if the repo asks for it
9999
- **Scope**: Use scopes the repo's PR lint allows (check `.github/workflows/` or contributing docs)
100100

101+
## 6. PR review follow-up (address maintainer comments)
102+
103+
Use this when an open PR already exists and reviewers left feedback. **Contribution repo** = the upstream project you fixed (not the Iynx `the-fixer` repo unless that is your target).
104+
105+
### Default artifact (do not commit)
106+
107+
- **Path:** `<contribution-repo-root>/.iynx/pr-review-feedback.md`
108+
- **Policy:** Never commit this file. It is local scratch for the agent.
109+
- **Gitignore:** The helper refuses the default path unless Git ignores it (`git check-ignore`). If the upstream repo does not ignore `.iynx/`, pass **`--output`** or set **`IYNX_PR_REVIEW_FEEDBACK_PATH`** to a path outside the repo (or add an ignore rule locally without committing it—prefer `--output`).
110+
111+
### Phase 1 — Normalize (existing clone)
112+
113+
From the contribution clone (e.g. `workspace/owner-repo/`):
114+
115+
```bash
116+
git fetch --all --prune
117+
gh pr checkout <PR_NUMBER>
118+
```
119+
120+
```powershell
121+
git fetch --all --prune
122+
gh pr checkout <PR_NUMBER>
123+
```
124+
125+
### Phase 1 — Normalize (PR only, no clone yet)
126+
127+
1. Inspect head vs base: `gh pr view <URL> --json headRepository,baseRepository`.
128+
2. If **head** equals **base** (same `nameWithOwner`): clone that repo, then `gh pr checkout <N>`.
129+
3. Else (fork PR): clone the **head** repo’s URL from JSON, add `upstream` to the **base** repo URL, then `gh pr checkout <N>` from that clone.
130+
131+
### Phase 2 — Fetch review text into markdown
132+
133+
From the **Iynx** project root (or any cwd if you use `--output` / env):
134+
135+
```bash
136+
# Inside contribution clone; writes .iynx/pr-review-feedback.md if gitignored
137+
python pr_review.py https://github.com/owner/repo/pull/42
138+
139+
python pr_review.py owner/repo#42
140+
python pr_review.py --repo owner/repo --pr 42
141+
python pr_review.py 42 --repo owner/repo
142+
```
143+
144+
```powershell
145+
cd path\to\contribution-clone
146+
python path\to\the-fixer\pr_review.py "https://github.com/owner/repo/pull/42"
147+
148+
python path\to\the-fixer\pr_review.py --repo owner/repo --pr 42 --output "$env:TEMP\pr-review-feedback.md"
149+
```
150+
151+
Requires **`gh`** installed and authenticated. If **`--output`** is omitted, **`IYNX_PR_REVIEW_FEEDBACK_PATH`** is used when set; otherwise the default is `.iynx/pr-review-feedback.md` under the contribution repo (requires that path to be gitignored).
152+
153+
### Phase 3 — Implement, verify, push
154+
155+
1. Read the markdown file; address each review thread; ask on the PR if something is ambiguous.
156+
2. Run tests (and lint/format) using `.iynx/context.json` `test_command` / `lint_command` when present, else CONTRIBUTING.
157+
3. Commit (do not add `pr-review-feedback.md`); push to the **same branch** as the PR head.
158+
159+
**Exit codes:** `0` = file written; `1` = usage or local validation; `2` = `gh`/GitHub error.
160+
161+
**Spec:** `docs/superpowers/specs/2026-03-24-pr-review-followup-design.md`
162+
101163
## Adapting to a Repo
102164

103165
Each repo has its own structure. Before starting:

0 commit comments

Comments
 (0)