chore(claude): rename pr skill to pull-request and fix automation gaps#3160
chore(claude): rename pr skill to pull-request and fix automation gaps#3160PierreBrisorgueil merged 6 commits intomasterfrom
Conversation
- Rename .claude/skills/pr/ → .claude/skills/pull-request/ with shorter description so the skill loads reliably in system-reminder - Fix monitor loop: push before reply/resolve, CI retry fallback, thread ID source - Add preliminary review pass after gh pr ready (CodeRabbit and ready-triggered bots) - Add 10-iteration safety limit clarification (preliminary pass not counted) - Add guardrail in CLAUDE.md to always invoke /pull-request when shipping work - Update feature/SKILL.md to reference /pull-request Closes #3159
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughRenames the PR skill from Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as "Developer"
participant Skill as "pull-request Skill"
participant GH as "GitHub (gh + API)"
participant CI as "CI"
participant Repo as "Repository"
Dev->>Skill: /pull-request (create draft PR)
Skill->>Repo: git push branch (create draft PR)
Skill->>GH: gh pr create (draft)
Skill->>CI: wait for CI to start (poll)
CI-->>Skill: CI queued / running / result
Skill->>GH: list unresolved review threads (GraphQL)
GH-->>Skill: return threads + IDs
Skill->>Skill: evaluate actionable comments
alt actionable comments exist
Skill->>Repo: apply fixes (batch commits) and push
Skill->>GH: gh pr ready / update
Skill->>CI: wait for CI (loop)
else no actionable comments and CI green
Skill->>Dev: stop (CI green + zero actionable)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/skills/pull-request/SKILL.md:
- Around line 157-162: The TOTAL calculation uses gh api --paginate piped to jq
'length', which only returns the last page's length; update the TOTAL assignment
(the shell variable TOTAL in the snippet that calls gh api
repos/.../issues/.../comments --paginate) to slurp and aggregate all pages
before computing length (use jq's slurp mode to merge the per-page arrays and
compute the combined length), so the script sums counts across pages rather than
reading only the final page.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.claude/skills/feature/SKILL.md.claude/skills/pr/SKILL.md.claude/skills/pr/references/monitoring.md.claude/skills/pull-request/SKILL.md.claude/skills/pull-request/references/monitoring.mdCLAUDE.md
💤 Files with no reviewable changes (2)
- .claude/skills/pr/SKILL.md
- .claude/skills/pr/references/monitoring.md
There was a problem hiding this comment.
Pull request overview
Renames the embedded Claude PR workflow skill from /pr to /pull-request and updates the skill content to close gaps in the autonomous PR monitoring loop (CI waiting, feedback handling, and stop conditions) within the repo’s internal .claude/ tooling.
Changes:
- Renamed the PR skill to
pull-requestand added updated monitoring/reference documentation under.claude/skills/pull-request/. - Updated
CLAUDE.mdand the/featureskill to point contributors toward/pull-requestfor PR lifecycle operations. - Removed the legacy
.claude/skills/pr/skill docs.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
CLAUDE.md |
Updates guardrails and the skills table to reference /pull-request. |
.claude/skills/pull-request/SKILL.md |
New PR lifecycle skill playbook with updated autonomous monitor loop steps. |
.claude/skills/pull-request/references/monitoring.md |
New gh/GraphQL reference commands for CI and review thread monitoring. |
.claude/skills/pr/SKILL.md |
Removes the old /pr skill doc. |
.claude/skills/pr/references/monitoring.md |
Removes the old monitoring reference doc. |
.claude/skills/feature/SKILL.md |
Adds a step directing users to /pull-request once verify passes. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
.claude/skills/pull-request/references/monitoring.md (1)
56-66:--paginate | jq 'map(...)'produces separate arrays per page.
gh api --paginateemits one JSON array per page;jq 'map(...)'(without-s) processes each independently, outputting multiple arrays. For display this is functional, but inconsistent with the-s 'add | …'pattern already applied in SKILL.md. Consider using slurp mode for a single flat list:♻️ Suggested consistency fix
-gh api repos/$OWNER/$REPO/pulls/$PR/comments --paginate \ - | jq 'map({id, user: .user.login, body: .body[0:100], line})' +gh api repos/$OWNER/$REPO/pulls/$PR/comments --paginate \ + | jq -s 'add | map({id, user: .user.login, body: .body[0:100], line})'-gh api repos/$OWNER/$REPO/issues/$PR/comments --paginate \ - | jq 'map({id, user: .user.login, body: .body[0:100]})' +gh api repos/$OWNER/$REPO/issues/$PR/comments --paginate \ + | jq -s 'add | map({id, user: .user.login, body: .body[0:100]})'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/skills/pull-request/references/monitoring.md around lines 56 - 66, The current gh api commands using --paginate piped to jq 'map(...)' produce separate arrays per page; change the jq usage to slurp mode and merge pages into a single array (use jq -s 'add | map({id, user: .user.login, body: .body[0:100], line})' for the pull-request comments command and jq -s 'add | map({id, user: .user.login, body: .body[0:100]})' for the issue comments command) so the output is a single flattened list while keeping the same fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/skills/pull-request/SKILL.md:
- Around line 139-157: Replace the literal "<number>" placeholder with the
previously defined PR variable ($PR) in the bash blocks that call the GitHub CLI
(specifically the commands like "gh pr checks <number> --watch" and the retry
loop using "gh pr checks <number>") so the script uses the PR variable; update
the occurrences in sections 6a and 6f to reference $PR (matching how other
blocks use $PR) and ensure all instances of "<number>" in those blocks are
changed to $PR so the commands execute with the actual PR number.
---
Nitpick comments:
In @.claude/skills/pull-request/references/monitoring.md:
- Around line 56-66: The current gh api commands using --paginate piped to jq
'map(...)' produce separate arrays per page; change the jq usage to slurp mode
and merge pages into a single array (use jq -s 'add | map({id, user:
.user.login, body: .body[0:100], line})' for the pull-request comments command
and jq -s 'add | map({id, user: .user.login, body: .body[0:100]})' for the issue
comments command) so the output is a single flattened list while keeping the
same fields.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.claude/skills/pull-request/SKILL.md.claude/skills/pull-request/references/monitoring.md.github/copilot-instructions.md.github/prompts/pr.prompt.md.github/prompts/pull-request.prompt.mdAGENTS.mdREADME.md
💤 Files with no reviewable changes (1)
- .github/prompts/pr.prompt.md
There was a problem hiding this comment.
♻️ Duplicate comments (1)
.claude/skills/pull-request/references/monitoring.md (1)
28-29:⚠️ Potential issue | 🟡 Minor
monitoring.mdstill has the unconditional--watch— inconsistent withSKILL.md.The retry loop here has no
CHECKS_FOUNDguard, so line 29'sgh pr checks "$PR" --watchstill executes unconditionally after all 5 retries, which can hang indefinitely if CI never starts.SKILL.md(lines 146–164) was updated with the correct guard; this reference snippet was not.🛠️ Proposed fix — align with
SKILL.md+CHECKS_FOUND=0 for i in 1 2 3 4 5; do if output=$(gh pr checks "$PR" 2>&1); then if echo "$output" | grep -q "no checks reported"; then sleep 30 # checks not started yet else - echo "$output" && break # checks detected + echo "$output" && CHECKS_FOUND=1 && break # checks detected fi else echo "$output" >&2 && sleep 30 # gh command failed, retry fi done -gh pr checks "$PR" --watch +[ "$CHECKS_FOUND" -eq 1 ] && gh pr checks "$PR" --watch🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/skills/pull-request/references/monitoring.md around lines 28 - 29, The snippet in monitoring.md runs gh pr checks "$PR" --watch unconditionally; replicate the SKILL.md fix by guarding the final watch invocation with the same CHECKS_FOUND check used in the retry loop: only run gh pr checks "$PR" --watch if CHECKS_FOUND is true (i.e., wrap the command in the same conditional used in SKILL.md), ensuring the retry loop's CHECKS_FOUND variable controls whether the watch is executed to avoid hanging when CI never starts.
🧹 Nitpick comments (1)
.claude/skills/pull-request/references/monitoring.md (1)
86-92: Use GraphQL variables instead of a hard-coded string literal forTHREAD_ID.Single quotes prevent shell variable expansion, so
"THREAD_ID"in the mutation is treated as a literal string. The idiomaticgh api graphqlapproach is to pass the value as a GraphQL variable using an additional field flag (e.g.,-f threadId="$THREAD_ID"), which avoids quoting issues entirely.♻️ Proposed refactor — use GraphQL variable binding
+THREAD_ID="<id-from-list-query>" gh api graphql -f query='mutation { - resolveReviewThread(input: {threadId: "THREAD_ID"}) { + resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } -}' +}' -f threadId="$THREAD_ID"Or equivalently, declare the variable in the operation signature:
THREAD_ID="<id-from-list-query>" gh api graphql \ -f threadId="$THREAD_ID" \ -f query='mutation Resolve($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/skills/pull-request/references/monitoring.md around lines 86 - 92, Replace the hard-coded string literal "THREAD_ID" in the GraphQL mutation passed to gh api graphql with a GraphQL variable binding: declare a variable (e.g., threadId) in the mutation signature and pass its value via gh's -f flag (for example -f threadId="$THREAD_ID"), then use that variable in the resolveReviewThread input (input: {threadId: $threadId}) so shell variable expansion works correctly and avoids the single-quote quoting issue.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.claude/skills/pull-request/references/monitoring.md:
- Around line 28-29: The snippet in monitoring.md runs gh pr checks "$PR"
--watch unconditionally; replicate the SKILL.md fix by guarding the final watch
invocation with the same CHECKS_FOUND check used in the retry loop: only run gh
pr checks "$PR" --watch if CHECKS_FOUND is true (i.e., wrap the command in the
same conditional used in SKILL.md), ensuring the retry loop's CHECKS_FOUND
variable controls whether the watch is executed to avoid hanging when CI never
starts.
---
Nitpick comments:
In @.claude/skills/pull-request/references/monitoring.md:
- Around line 86-92: Replace the hard-coded string literal "THREAD_ID" in the
GraphQL mutation passed to gh api graphql with a GraphQL variable binding:
declare a variable (e.g., threadId) in the mutation signature and pass its value
via gh's -f flag (for example -f threadId="$THREAD_ID"), then use that variable
in the resolveReviewThread input (input: {threadId: $threadId}) so shell
variable expansion works correctly and avoids the single-quote quoting issue.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3160 +/- ##
=======================================
Coverage 89.86% 89.86%
=======================================
Files 52 52
Lines 1164 1164
Branches 234 234
=======================================
Hits 1046 1046
Misses 107 107
Partials 11 11 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Summary
.claude/skills/pr/→.claude/skills/pull-request/and fix multiple automation gaps in the monitor loopprskill was not being loaded into Claude Code's system-reminder (description too long + late addition), causing the PR workflow to be silently skipped. Several loop gaps also caused incorrect behavior when the skill was used.Scope
.claude/skills/(internal tooling only, no application code)nonelowValidation
npm run lintnpm testGuardrails check
.env*,secrets/**, keys, tokens)Notes for reviewers
.claude/andCLAUDE.mdSummary by CodeRabbit
Documentation
Chores