From 0898716c37f531eefc4c77c394cc592fb3eca6b7 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Tue, 12 May 2026 12:13:04 +0000 Subject: [PATCH 01/13] Add get-reviews skill for handling PR reviews Introduce a new agent skill that streamlines fetching, organizing, and resolving GitHub pull request reviews. The skill provides: - SKILL.md documenting the end-to-end workflow: fetching reviews via the GitHub GraphQL API, organizing them under plans/{PR_NUMBER}/, and resolving them by applying or dismissing with proper commit references and English translations. - fetch_reviews.sh as a reusable GraphQL query script for retrieving review threads with pagination support. - review.md as a template for individual review files, capturing the review metadata, comments, judgement, and resolution status. Assisted-by: Claude Code:claude-opus-4-7 --- .agents/skills/get-reviews/SKILL.md | 94 +++++++++++++++ .agents/skills/get-reviews/fetch_reviews.sh | 29 +++++ .agents/skills/get-reviews/review.md | 125 ++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 .agents/skills/get-reviews/SKILL.md create mode 100644 .agents/skills/get-reviews/fetch_reviews.sh create mode 100644 .agents/skills/get-reviews/review.md diff --git a/.agents/skills/get-reviews/SKILL.md b/.agents/skills/get-reviews/SKILL.md new file mode 100644 index 000000000..cffbfbbb3 --- /dev/null +++ b/.agents/skills/get-reviews/SKILL.md @@ -0,0 +1,94 @@ +--- +name: get-reviews +description: >- + This skill is utilized when requesting reviews from GitHub pull requests. + Get the reviews, organize, and resolve them by applying or dismissing. +argument-hint: "Provide the number of the pull request to get the reviews." +--- + + + +Get reviews from GitHub pull requests +===================================== + +This skill is utilized when requesting reviews from GitHub pull requests. + +1. Get the reviews. +2. Organize the reviews. +3. Resolve the reviews by applying or dismissing them. + + +Get the reviews +--------------- + +To get the reviews from a GitHub pull request, you can use the GitHub API. +Check the [`gh` CLI tool][gh] is installed and authenticated. +`gh auth status` can be used to check the authentication status. +If `gh` isn't installed, try installing it by `apt install gh`. +If authentication is not set up, tell the contributor to run `gh auth login` +to authenticate with GitHub. + +Use the GraphQL API to fetch the reviews for a specific pull request. +Check [fetch\_reviews.sh](./fetch_reviews.sh) to fetch the reviews +and save them in a JSON file: + + - Replace `$VARIABLES` with the actual values or variables in the command. + - If already saved reviews existed, use `after: $LAST_REVIEW_ID` instead of + `first: $NUMBER_OF_THREADS` to fetch new reviews. + - Use `jq` to filter the reviews and information if necessary. + +[gh]: https://cli.github.com/ + + +Organize the reviews +-------------------- + +After fetching the PR and its reviews, organize the reviews. +[*plans* directory in the root](../../../plans/) is a good place to store them. + + - *plans/{PR\_NUMBER}/index.md*: The main file for the PR. + - The body of the PR + - *plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}.md*: The file for each review + which is not resolved. + - After applying or dismissing the review, move the file to + *plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}.md*. + - If the review file is too long, move the content to + \**plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}/index.md*, and separate the + content into multiple files in the same directory. In this case, after + resolving the review, move the whole directory to + *plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}/*. + - *plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}.md*: The file for each + review which is resolved. + +The format of review files should be as [review.md](./review.md). + +All related information with the review should be stored in +*plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}.md* or the files in +*plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}/*. + + +Resolve the reviews +------------------- + +Let the contributor read the review files, decide the judgement and the plans +for each review, and let them update the review files if necessary. +After the contributor decides the judgement and the plans, apply or dismiss the +reviews based on the files. + +Categorize the reviews and the plans, and apply them at once by category. +After applying the review, use [`/commit` skill](../commit/SKILL.md) to commit +the changes. The commit message should include the related review links. +`https://github.com/fedify-dev/fedify/pull/{PR_NUMBER}#discussion_r{REVIEW_THREAD.COMMENTS[0].DATABASE_ID})` + +After committing the changes, update the review file to include the commit hash +and the comment section. If the review is dismissed, update the review file to +include the reason for dismissing and the comment section. + +If the `Comments` are written only in the contributor's language, provide an +English translation and have the contributor review it. If they are written in +both languages, check for any discrepancies between the two. If differences +exist between the two versions, review them based on the facts and revise +the English version to match the content in the contributor's language. + +Post all of the review in English, even if the file written in the contributor's +native language. The comments should be polite and constructive. diff --git a/.agents/skills/get-reviews/fetch_reviews.sh b/.agents/skills/get-reviews/fetch_reviews.sh new file mode 100644 index 000000000..2b160028c --- /dev/null +++ b/.agents/skills/get-reviews/fetch_reviews.sh @@ -0,0 +1,29 @@ +mkdir -p 'plans/$PR_NUMBER/fetched' +gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { + repository(owner: $owner, name: $repo) { + pullRequest(number: $number) { + reviewThreads(first: $NUMBER_OF_THREADS) { + nodes { + id + isResolved + isOutdated + path + line + comments(first: $NUMBER_OF_COMMENTS_PER_THREAD) { + nodes { + id + databaseId + author { login } + body + url + createdAt + } + } + } + } + } + } +}' -F owner=fedify-dev -F repo=fedify -F number=$PR_NUMBER \ +> 'plans/$PR_NUMBER/fetched/$CURRENT_TIMESTAMP_MMDDHHMM.json' + +# cspell: ignore MMDDHHMM diff --git a/.agents/skills/get-reviews/review.md b/.agents/skills/get-reviews/review.md new file mode 100644 index 000000000..ecc28ba45 --- /dev/null +++ b/.agents/skills/get-reviews/review.md @@ -0,0 +1,125 @@ +--- +id: REVIEW_ID +description: summary of the review +link: the link to the review on GitHub +links: + - If there are multiple links related to the review, + - list all the links. + - `link`–`links` are mutually exclusive. +commit: the hash of commit after applying the review to add the comment +commits: + - If the review applies to multiple commits, list the hashes of the commits + - after applying the review, update the list to include the new commit hash + - `commit`–`commits` are mutually exclusive. `commit` and `commits` are + - optional, and only used when the review is applied. +--- + + + +Title +===== + + + + +Summary +------- + + + + +Judgement +--------- + + + + +Plans +----- + + + + +Comments +-------- + + From f1152174091aa536d5f0cf6e92299c189d25772f Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 03:45:32 +0000 Subject: [PATCH 02/13] Fetch PR reviews and link review threads to their reviews and comments Extend the get-reviews skill so that the fetch script also retrieves PullRequestReview nodes (id, author, body, state, etc.) alongside the existing review threads, and add a `pullRequestReview` back-reference on each review thread comment so threads can be grouped by the review that created them. Update the SKILL.md to point future invocations to the cached JSON in *plans/{PR_NUMBER}/fetched/* when more context (e.g., the review a thread belongs to, or the original body of a comment) is needed, instead of re-fetching from GitHub. Update the review.md template so the `links` metadata can include URLs to related PR comments (issue comments) and review thread replies that provide additional context for the review. Assisted-by: Claude Code:claude-opus-4-7 --- .agents/skills/get-reviews/SKILL.md | 6 +++++ .agents/skills/get-reviews/fetch_reviews.sh | 25 +++++++++++++++++++++ .agents/skills/get-reviews/review.md | 3 +++ 3 files changed, 34 insertions(+) diff --git a/.agents/skills/get-reviews/SKILL.md b/.agents/skills/get-reviews/SKILL.md index cffbfbbb3..1f77323b0 100644 --- a/.agents/skills/get-reviews/SKILL.md +++ b/.agents/skills/get-reviews/SKILL.md @@ -37,6 +37,12 @@ and save them in a JSON file: `first: $NUMBER_OF_THREADS` to fetch new reviews. - Use `jq` to filter the reviews and information if necessary. +The fetched JSON files in *plans/{PR\_NUMBER}/fetched/* contain the raw data +of PR comments, reviews, and review threads (with `pullRequestReview` +back-references on thread comments). When more context is needed later +(e.g., to resolve which review a thread belongs to, or to check the original +body of a comment), refer back to these files instead of re-fetching. + [gh]: https://cli.github.com/ diff --git a/.agents/skills/get-reviews/fetch_reviews.sh b/.agents/skills/get-reviews/fetch_reviews.sh index 2b160028c..064c5a9df 100644 --- a/.agents/skills/get-reviews/fetch_reviews.sh +++ b/.agents/skills/get-reviews/fetch_reviews.sh @@ -2,6 +2,27 @@ mkdir -p 'plans/$PR_NUMBER/fetched' gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $number) { + comments(first: $NUMBER_OF_PR_COMMENTS) { + nodes { + id + databaseId + author { login } + body + url + createdAt + } + } + reviews(first: $NUMBER_OF_REVIEWS) { + nodes { + id + databaseId + author { login } + body + state + url + createdAt + } + } reviewThreads(first: $NUMBER_OF_THREADS) { nodes { id @@ -17,6 +38,10 @@ gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { body url createdAt + pullRequestReview { + id + databaseId + } } } } diff --git a/.agents/skills/get-reviews/review.md b/.agents/skills/get-reviews/review.md index ecc28ba45..250df7c40 100644 --- a/.agents/skills/get-reviews/review.md +++ b/.agents/skills/get-reviews/review.md @@ -5,6 +5,9 @@ link: the link to the review on GitHub links: - If there are multiple links related to the review, - list all the links. + - Include links to related PR comments (issue comments) and review thread + - replies that provide additional context for this review. Use the `url` + - field of each comment from the fetched JSON. - `link`–`links` are mutually exclusive. commit: the hash of commit after applying the review to add the comment commits: From 4b6fd9ce606581f942304bf165fd5dc1dc9b22ad Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 04:17:49 +0000 Subject: [PATCH 03/13] Add harnesses for agents often mistaking parts Add harnesses for agents often mistaking parts --- .agents/skills/get-reviews/SKILL.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.agents/skills/get-reviews/SKILL.md b/.agents/skills/get-reviews/SKILL.md index 1f77323b0..ec0870187 100644 --- a/.agents/skills/get-reviews/SKILL.md +++ b/.agents/skills/get-reviews/SKILL.md @@ -66,12 +66,23 @@ After fetching the PR and its reviews, organize the reviews. - *plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}.md*: The file for each review which is resolved. +**Don't use the first comment of the review thread as the review ID.** +The ID of the review thread starts with “PRRT\_”. +Use the first comment ID of the review thread only on the link. + The format of review files should be as [review.md](./review.md). +The files should be written in the contributor's language. But the title of +the item in the file (e.g., “Summary”, “Judgement”, “Plans”) should be in +English for consistency. + +Empty the space between the “Title” and the “Summary” sections. All related information with the review should be stored in *plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}.md* or the files in *plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}/*. +After organizing the reviews, show the links to the files to the contributor. + Resolve the reviews ------------------- From 096c8170a6c7585657d1243aa18e3280657a519f Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 04:32:33 +0000 Subject: [PATCH 04/13] Tidy `get-reviews` skill helper files Name the path-building pieces of `fetch_reviews.sh` (`PR_PATH`, `FETCHED_PATH`, `TIMESTAMP`, `FETCHED_FILE`) so the script reads as a single recipe instead of repeating the same path expression twice, and pipe the response through `jq .` so saved JSON is pretty-printed and diffable across fetches. In `review.md`, capitalise the description sentences for `link` and `commit` to match the other frontmatter descriptions, and join a two-line `links` bullet that was needlessly wrapped. These are cosmetic preparations for the upcoming review-driven fixes on this branch; they do not address any specific reviewer comment. Assisted-by: Claude Code:claude-opus-4-7 --- .agents/skills/get-reviews/fetch_reviews.sh | 8 ++++++-- .agents/skills/get-reviews/review.md | 7 +++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.agents/skills/get-reviews/fetch_reviews.sh b/.agents/skills/get-reviews/fetch_reviews.sh index 064c5a9df..3de26de3b 100644 --- a/.agents/skills/get-reviews/fetch_reviews.sh +++ b/.agents/skills/get-reviews/fetch_reviews.sh @@ -1,4 +1,8 @@ -mkdir -p 'plans/$PR_NUMBER/fetched' +PR_PATH="plans/$PR_NUMBER" +FETCHED_PATH="$PR_PATH/fetched" +mkdir -p "$FETCHED_PATH" +TIMESTAMP=$(date +"%m%d%H%M") +FETCHED_FILE="$FETCHED_PATH/$TIMESTAMP.json" gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $number) { @@ -49,6 +53,6 @@ gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { } } }' -F owner=fedify-dev -F repo=fedify -F number=$PR_NUMBER \ -> 'plans/$PR_NUMBER/fetched/$CURRENT_TIMESTAMP_MMDDHHMM.json' +| jq . > "$FETCHED_FILE" # cspell: ignore MMDDHHMM diff --git a/.agents/skills/get-reviews/review.md b/.agents/skills/get-reviews/review.md index 250df7c40..e426ed761 100644 --- a/.agents/skills/get-reviews/review.md +++ b/.agents/skills/get-reviews/review.md @@ -1,15 +1,14 @@ --- id: REVIEW_ID description: summary of the review -link: the link to the review on GitHub +link: The link to the review on GitHub links: - - If there are multiple links related to the review, - - list all the links. + - If there are multiple links related to the review, list all the links. - Include links to related PR comments (issue comments) and review thread - replies that provide additional context for this review. Use the `url` - field of each comment from the fetched JSON. - `link`–`links` are mutually exclusive. -commit: the hash of commit after applying the review to add the comment +commit: The hash of commit after applying the review to add the comment commits: - If the review applies to multiple commits, list the hashes of the commits - after applying the review, update the list to include the new commit hash From c3827ff01cf9cc5f2a0e66835384df1b44cf2319 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 04:34:07 +0000 Subject: [PATCH 05/13] Declare GraphQL variables in `fetch_reviews.sh` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous query body referenced `$NUMBER_OF_THREADS` and `$NUMBER_OF_COMMENTS_PER_THREAD` inside `gh api graphql -f query='…'` without declaring them in the `query(...)` header or forwarding them via `-F`, so every invocation came back with `Variable $NUMBER_OF_THREADS is not defined`. The script could not have completed a single fetch in this state. Declare `$prComments`, `$reviews`, `$threads`, and `$comments` as proper GraphQL Int parameters and forward the corresponding `$NUMBER_OF_*` shell variables — the ones SKILL.md tells the user to substitute — via matching `-F` flags. Also add a `#!/usr/bin/env bash` shebang so the script is self-contained, and quote `-F number="$PR_NUMBER"` for consistency with the other parameters. The single-quoted redirect path that https://github.com/fedify-dev/fedify/pull/765#discussion_r3226409530 flagged is already addressed: the prior refactor pointed the redirect target at the double-quoted `"$FETCHED_FILE"` shell variable, so the literal `$PR_NUMBER` directory bug it described can no longer occur. Addresses: - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226409498 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226424774 Assisted-by: Claude Code:claude-opus-4-7 --- .agents/skills/get-reviews/fetch_reviews.sh | 30 ++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/.agents/skills/get-reviews/fetch_reviews.sh b/.agents/skills/get-reviews/fetch_reviews.sh index 3de26de3b..e7818bc38 100644 --- a/.agents/skills/get-reviews/fetch_reviews.sh +++ b/.agents/skills/get-reviews/fetch_reviews.sh @@ -1,12 +1,21 @@ +#!/usr/bin/env bash PR_PATH="plans/$PR_NUMBER" FETCHED_PATH="$PR_PATH/fetched" mkdir -p "$FETCHED_PATH" TIMESTAMP=$(date +"%m%d%H%M") FETCHED_FILE="$FETCHED_PATH/$TIMESTAMP.json" -gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { +gh api graphql -f query='query( + $owner: String!, + $repo: String!, + $number: Int!, + $prComments: Int!, + $reviews: Int!, + $threads: Int!, + $comments: Int! +) { repository(owner: $owner, name: $repo) { pullRequest(number: $number) { - comments(first: $NUMBER_OF_PR_COMMENTS) { + comments(first: $prComments) { nodes { id databaseId @@ -16,7 +25,7 @@ gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { createdAt } } - reviews(first: $NUMBER_OF_REVIEWS) { + reviews(first: $reviews) { nodes { id databaseId @@ -27,14 +36,14 @@ gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { createdAt } } - reviewThreads(first: $NUMBER_OF_THREADS) { + reviewThreads(first: $threads) { nodes { id isResolved isOutdated path line - comments(first: $NUMBER_OF_COMMENTS_PER_THREAD) { + comments(first: $comments) { nodes { id databaseId @@ -52,7 +61,14 @@ gh api graphql -f query='query($owner: String!, $repo: String!, $number: Int!) { } } } -}' -F owner=fedify-dev -F repo=fedify -F number=$PR_NUMBER \ -| jq . > "$FETCHED_FILE" +}' \ + -F owner=fedify-dev \ + -F repo=fedify \ + -F number="$PR_NUMBER" \ + -F prComments="$NUMBER_OF_PR_COMMENTS" \ + -F reviews="$NUMBER_OF_REVIEWS" \ + -F threads="$NUMBER_OF_THREADS" \ + -F comments="$NUMBER_OF_COMMENTS_PER_THREAD" \ + | jq . > "$FETCHED_FILE" # cspell: ignore MMDDHHMM From 1e4fd43cbeb5a1218bcffdac769cbdbe534960c1 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 04:37:27 +0000 Subject: [PATCH 06/13] Wire cursor pagination and fix `get-reviews` SKILL.md typos Switch `fetch_reviews.sh` to cursor-based incremental fetches and correct three typos in the surrounding documentation. Incremental fetches were previously described as "use `after: $LAST_REVIEW_ID`", but GitHub GraphQL's `after` argument takes a base64 cursor (`pageInfo.endCursor`), not a review-thread node ID, so following the instructions literally produced API errors. Declare `$after: String` in the query header, select `pageInfo { hasNextPage endCursor }` on `reviewThreads`, and conditionally forward `-F after="$LAST_CURSOR"` only when the shell variable is set so the first-time fetch keeps working unchanged. Update SKILL.md to describe the cursor flow in matching terms. The three typo fixes: - Drop a stray backslash before an italic path so the path renders as italics consistently with the rest of the list. - Remove a stray trailing `)` on the example discussion URL that contributors copy verbatim into commit messages. - Rephrase "Post all of the review in English" to "Post all review comments in English". `plans/` is already covered by *.gitignore* (line 21), so the related review thread needs no code change. Addresses: - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226409564 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226409567 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226409576 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3227774687 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3227774730 Assisted-by: Claude Code:claude-opus-4-7 --- .agents/skills/get-reviews/SKILL.md | 13 +++++++------ .agents/skills/get-reviews/fetch_reviews.sh | 10 ++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.agents/skills/get-reviews/SKILL.md b/.agents/skills/get-reviews/SKILL.md index ec0870187..97bfebb57 100644 --- a/.agents/skills/get-reviews/SKILL.md +++ b/.agents/skills/get-reviews/SKILL.md @@ -33,8 +33,9 @@ Check [fetch\_reviews.sh](./fetch_reviews.sh) to fetch the reviews and save them in a JSON file: - Replace `$VARIABLES` with the actual values or variables in the command. - - If already saved reviews existed, use `after: $LAST_REVIEW_ID` instead of - `first: $NUMBER_OF_THREADS` to fetch new reviews. + - For incremental fetches, save `pageInfo.endCursor` from the previous + fetch and pass it as `after: $LAST_CURSOR` (a base64 cursor, not a + review thread node ID) so the query returns only new review threads. - Use `jq` to filter the reviews and information if necessary. The fetched JSON files in *plans/{PR\_NUMBER}/fetched/* contain the raw data @@ -59,7 +60,7 @@ After fetching the PR and its reviews, organize the reviews. - After applying or dismissing the review, move the file to *plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}.md*. - If the review file is too long, move the content to - \**plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}/index.md*, and separate the + *plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}/index.md*, and separate the content into multiple files in the same directory. In this case, after resolving the review, move the whole directory to *plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}/*. @@ -95,7 +96,7 @@ reviews based on the files. Categorize the reviews and the plans, and apply them at once by category. After applying the review, use [`/commit` skill](../commit/SKILL.md) to commit the changes. The commit message should include the related review links. -`https://github.com/fedify-dev/fedify/pull/{PR_NUMBER}#discussion_r{REVIEW_THREAD.COMMENTS[0].DATABASE_ID})` +`https://github.com/fedify-dev/fedify/pull/{PR_NUMBER}#discussion_r{REVIEW_THREAD.COMMENTS[0].DATABASE_ID}` After committing the changes, update the review file to include the commit hash and the comment section. If the review is dismissed, update the review file to @@ -107,5 +108,5 @@ both languages, check for any discrepancies between the two. If differences exist between the two versions, review them based on the facts and revise the English version to match the content in the contributor's language. -Post all of the review in English, even if the file written in the contributor's -native language. The comments should be polite and constructive. +Post all review comments in English, even if the file written in the +contributor's native language. The comments should be polite and constructive. diff --git a/.agents/skills/get-reviews/fetch_reviews.sh b/.agents/skills/get-reviews/fetch_reviews.sh index e7818bc38..a618b97e8 100644 --- a/.agents/skills/get-reviews/fetch_reviews.sh +++ b/.agents/skills/get-reviews/fetch_reviews.sh @@ -11,7 +11,8 @@ gh api graphql -f query='query( $prComments: Int!, $reviews: Int!, $threads: Int!, - $comments: Int! + $comments: Int!, + $after: String ) { repository(owner: $owner, name: $repo) { pullRequest(number: $number) { @@ -36,7 +37,11 @@ gh api graphql -f query='query( createdAt } } - reviewThreads(first: $threads) { + reviewThreads(first: $threads, after: $after) { + pageInfo { + hasNextPage + endCursor + } nodes { id isResolved @@ -69,6 +74,7 @@ gh api graphql -f query='query( -F reviews="$NUMBER_OF_REVIEWS" \ -F threads="$NUMBER_OF_THREADS" \ -F comments="$NUMBER_OF_COMMENTS_PER_THREAD" \ + ${LAST_CURSOR:+-F after="$LAST_CURSOR"} \ | jq . > "$FETCHED_FILE" # cspell: ignore MMDDHHMM From ee571a77a6de06d035d6ab773d99c1970574e0e3 Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 04:38:52 +0000 Subject: [PATCH 07/13] Rewrite review.md frontmatter and fix two body typos The frontmatter used to expose both `link` and `links`, and both `commit` and `commits`, while telling the reader inside the YAML that the pairs were mutually exclusive. Every freshly copied review file therefore started out internally self-contradictory. Keep `link` and `commit` active by default, and demote `links` / `commits` to commented-out YAML examples right below them, so a new review file is in a consistent shape from the moment it's created. The rewrite also removes the en-dash lines and uneven YAML list-marker spacing that three other review threads asked us to fix, so those threads no longer have any text to point at. Two body typos: - Insert the missing space in `insufficient,use`. - Insert the missing "to" in `evaluate the review explain how`. Addresses: - https://github.com/fedify-dev/fedify/pull/765#discussion_r3227774763 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226424803 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226424804 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226409534 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226409542 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226424811 - https://github.com/fedify-dev/fedify/pull/765#discussion_r3226409555 Assisted-by: Claude Code:claude-opus-4-7 --- .agents/skills/get-reviews/review.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/.agents/skills/get-reviews/review.md b/.agents/skills/get-reviews/review.md index e426ed761..0c97e2cef 100644 --- a/.agents/skills/get-reviews/review.md +++ b/.agents/skills/get-reviews/review.md @@ -2,18 +2,19 @@ id: REVIEW_ID description: summary of the review link: The link to the review on GitHub -links: - - If there are multiple links related to the review, list all the links. - - Include links to related PR comments (issue comments) and review thread - - replies that provide additional context for this review. Use the `url` - - field of each comment from the fetched JSON. - - `link`–`links` are mutually exclusive. +# If more than one URL is relevant — related PR comments or review-thread +# replies that provide additional context — use `links` instead of `link`. +# Use the `url` field of each comment from the fetched JSON. +# links: +# - https://github.com/.../pull/123#discussion_r4567 +# - https://github.com/.../pull/123#discussion_r4568 commit: The hash of commit after applying the review to add the comment -commits: - - If the review applies to multiple commits, list the hashes of the commits - - after applying the review, update the list to include the new commit hash - - `commit`–`commits` are mutually exclusive. `commit` and `commits` are - - optional, and only used when the review is applied. +# If the review was applied across multiple commits, use `commits` instead +# of `commit`. Both fields are optional and only set after the review is +# applied. +# commits: +# - abc1234 +# - def5678 --- @@ -49,7 +50,7 @@ Judgement - **NEEDS DISCUSSION**: If the review needs further discussion, such as about direction of the project or design choices. Try to use these words to indicate judgement status whenever possible, - but if you feel they are truly insufficient,use an appropriate word + but if you feel they are truly insufficient, use an appropriate word and then update this part of *SKILL.md*. After the first line, explain the judgement in more detail. @@ -112,7 +113,7 @@ Comments on the **WRONG** part, and the correct parts based on the **CORRECT** part. If the review is judged as **NEEDS EVALUATION**, write the comments to - evaluate the review explain how to evaluate the review, the test results, + evaluate the review to explain how to evaluate the review, the test results, and the resulting application/rejection details. - If the results of the evaluation are the review is correct, write comments referring to the **CORRECT** part. From 49738f8a17792f4d970d09d698325912dccf942c Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 05:12:57 +0000 Subject: [PATCH 08/13] Add harnesses for agents often mistaking parts --- .agents/skills/get-reviews/SKILL.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.agents/skills/get-reviews/SKILL.md b/.agents/skills/get-reviews/SKILL.md index 97bfebb57..77cd73894 100644 --- a/.agents/skills/get-reviews/SKILL.md +++ b/.agents/skills/get-reviews/SKILL.md @@ -110,3 +110,10 @@ the English version to match the content in the contributor's language. Post all review comments in English, even if the file written in the contributor's native language. The comments should be polite and constructive. + +After resolving the reviews, pushing commits, posting comments, and updating +the reviews as resolved, move the review files to +*plans/{PR\_NUMBER}/reviews/resolved*. Before moving the files, check status and +comments of the PR from GitHub. Use [fetch\_reviews.sh](./fetch_reviews.sh), +but instead of fetching all reviews and attributes, fetch only the necessary +attributes to check the review status and comments. From 5877fb2285946162795a39c57cac8a6c28743bef Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 05:44:02 +0000 Subject: [PATCH 09/13] Add harnesses for about non-review thread --- .agents/skills/get-reviews/SKILL.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.agents/skills/get-reviews/SKILL.md b/.agents/skills/get-reviews/SKILL.md index 77cd73894..827830084 100644 --- a/.agents/skills/get-reviews/SKILL.md +++ b/.agents/skills/get-reviews/SKILL.md @@ -71,6 +71,23 @@ After fetching the PR and its reviews, organize the reviews. The ID of the review thread starts with “PRRT\_”. Use the first comment ID of the review thread only on the link. +Review threads aren't the only place that asks for changes. A PR-level +comment (in `comments` of the fetched JSON, whose ID starts with “IC\_”) +or the body of a review (in `reviews` of the fetched JSON, whose ID starts +with “PRR\_”) can also point out things to fix. When such a comment or +review body requests modifications, organize it as its own review file +alongside the review-thread files, using the same directory layout and +naming rules: + + - Use the node ID of the PR comment (“IC\_…”) or the review (“PRR\_…”) + as the `{REVIEW\_ID}` in the file path. + - If a PR comment or review body only contains approval, general + impressions, questions without a modification request, or other content + with nothing to fix, skip it and do not create a file for it. + - If only a part of a longer PR comment or review body requests changes, + create a file only for that request and quote the relevant excerpt in + the file so the context is preserved. + The format of review files should be as [review.md](./review.md). The files should be written in the contributor's language. But the title of the item in the file (e.g., “Summary”, “Judgement”, “Plans”) should be in From 79a5914637984afdd3b39c0a1edaec3f5a952f7f Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 06:11:32 +0000 Subject: [PATCH 10/13] Add harnesses for agents often mistaking parts --- .agents/skills/get-reviews/SKILL.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.agents/skills/get-reviews/SKILL.md b/.agents/skills/get-reviews/SKILL.md index 827830084..420ad2477 100644 --- a/.agents/skills/get-reviews/SKILL.md +++ b/.agents/skills/get-reviews/SKILL.md @@ -89,6 +89,7 @@ naming rules: the file so the context is preserved. The format of review files should be as [review.md](./review.md). +Read the reviews and fill the format as a draft with the related information. The files should be written in the contributor's language. But the title of the item in the file (e.g., “Summary”, “Judgement”, “Plans”) should be in English for consistency. From c479e9c35611e92fe9b0803389bded06c3c7629b Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 06:17:58 +0000 Subject: [PATCH 11/13] Fail fast on missing env vars in `fetch_reviews.sh` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without any guards the script trusted `PR_NUMBER` and the four `NUMBER_OF_*` variables to be set. Missing ones expanded to empty strings, so the script silently constructed paths like `plans//fetched/...` and forwarded empty `-F threads=`, `-F comments=` arguments. `gh` would then reject the call with a generic GraphQL error instead of pointing at the missing variable, while the empty directory had already been created. Add `set -euo pipefail` and a `: "${VAR:?…}"` guard for each of the five required variables, so the script aborts at the missing variable with a clear "VAR is required" message before touching the filesystem or talking to GitHub. `LAST_CURSOR` is intentionally not guarded — it is the optional incremental-fetch cursor and is referenced only through `${LAST_CURSOR:+-F after="$LAST_CURSOR"}`, which is safe under `set -u`. Addresses: - https://github.com/fedify-dev/fedify/pull/765#discussion_r3239351401 Assisted-by: Claude Code:claude-opus-4-7 --- .agents/skills/get-reviews/fetch_reviews.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.agents/skills/get-reviews/fetch_reviews.sh b/.agents/skills/get-reviews/fetch_reviews.sh index a618b97e8..febedc055 100644 --- a/.agents/skills/get-reviews/fetch_reviews.sh +++ b/.agents/skills/get-reviews/fetch_reviews.sh @@ -1,4 +1,12 @@ #!/usr/bin/env bash +set -euo pipefail + +: "${PR_NUMBER:?PR_NUMBER is required}" +: "${NUMBER_OF_PR_COMMENTS:?NUMBER_OF_PR_COMMENTS is required}" +: "${NUMBER_OF_REVIEWS:?NUMBER_OF_REVIEWS is required}" +: "${NUMBER_OF_THREADS:?NUMBER_OF_THREADS is required}" +: "${NUMBER_OF_COMMENTS_PER_THREAD:?NUMBER_OF_COMMENTS_PER_THREAD is required}" + PR_PATH="plans/$PR_NUMBER" FETCHED_PATH="$PR_PATH/fetched" mkdir -p "$FETCHED_PATH" From c72366ab76e520939b533c4cbd7ccbd96491325c Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 21:16:38 +0000 Subject: [PATCH 12/13] List required env vars for `fetch_reviews.sh` in SKILL.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `Get the reviews` section previously said only "Replace `$VARIABLES` with the actual values or variables in the command", which left readers to open `fetch_reviews.sh` to discover which variables the script actually expects. Replace that single line with two complementary blocks: - A one-line invocation example pre-filling all five required variables (`PR_NUMBER`, `NUMBER_OF_PR_COMMENTS`, `NUMBER_OF_REVIEWS`, `NUMBER_OF_THREADS`, `NUMBER_OF_COMMENTS_PER_THREAD`) plus the optional `LAST_CURSOR`. - A bullet list explaining what each variable controls. The script itself is unchanged — its fail-fast guards already cover missing values. Addresses: - https://github.com/fedify-dev/fedify/pull/765#discussion_r3239483648 Assisted-by: Claude Code:claude-opus-4-7 --- .agents/skills/get-reviews/SKILL.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.agents/skills/get-reviews/SKILL.md b/.agents/skills/get-reviews/SKILL.md index 420ad2477..f0639d9e1 100644 --- a/.agents/skills/get-reviews/SKILL.md +++ b/.agents/skills/get-reviews/SKILL.md @@ -32,10 +32,28 @@ Use the GraphQL API to fetch the reviews for a specific pull request. Check [fetch\_reviews.sh](./fetch_reviews.sh) to fetch the reviews and save them in a JSON file: - - Replace `$VARIABLES` with the actual values or variables in the command. + - Fill the variables in the command and run the command to fetch the reviews: + + ~~~~ bash + # Omit the new lines + PR_NUMBER= NUMBER_OF_PR_COMMENTS= NUMBER_OF_REVIEWS= \ + NUMBER_OF_THREADS= NUMBER_OF_COMMENTS_PER_THREAD= LAST_CURSOR= \ + bash .agents/skills/get-reviews/fetch_reviews.sh + ~~~~ + + + - `PR_NUMBER`: The number of the pull request to fetch reviews from. + - `NUMBER_OF_PR_COMMENTS`: The number of PR comments to fetch. + - `NUMBER_OF_REVIEWS`: The number of reviews to fetch. + - `NUMBER_OF_THREADS`: The number of review threads to fetch. + - `NUMBER_OF_COMMENTS_PER_THREAD`: + The number of comments per review thread to fetch. + - `LAST_CURSOR`: The cursor for incremental fetches. Optional. + - For incremental fetches, save `pageInfo.endCursor` from the previous fetch and pass it as `after: $LAST_CURSOR` (a base64 cursor, not a review thread node ID) so the query returns only new review threads. + - Use `jq` to filter the reviews and information if necessary. The fetched JSON files in *plans/{PR\_NUMBER}/fetched/* contain the raw data From 7b91c4af87c9196ab2f0d1aa1946bf9cc7fffb7e Mon Sep 17 00:00:00 2001 From: ChanHaeng Lee <2chanhaeng@gmail.com> Date: Thu, 14 May 2026 21:17:50 +0000 Subject: [PATCH 13/13] Replace unused comment with file path logging --- .agents/skills/get-reviews/fetch_reviews.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.agents/skills/get-reviews/fetch_reviews.sh b/.agents/skills/get-reviews/fetch_reviews.sh index febedc055..4a607a1fe 100644 --- a/.agents/skills/get-reviews/fetch_reviews.sh +++ b/.agents/skills/get-reviews/fetch_reviews.sh @@ -85,4 +85,4 @@ gh api graphql -f query='query( ${LAST_CURSOR:+-F after="$LAST_CURSOR"} \ | jq . > "$FETCHED_FILE" -# cspell: ignore MMDDHHMM +echo "Fetched reviews and comments are saved to $FETCHED_FILE"