skills/review-reply/SKILL.md
Review PR comments, discuss improvements, and reply with resolution status. TRIGGER when: user asks to review PR feedback, check review comments, address reviewer suggestions, or handle code review (e.g., "리뷰 확인해줘", "review comments", "피드백 반영해줘"). DO NOT TRIGGER when: user is creating PRs, committing, or performing git operations without review intent.
npx skillsauth add chanmuzi/git-conventions review-replyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Parse $ARGUMENTS to extract a PR number or URL.
If not provided, detect from the current branch:
gh pr view --json number --jq '.number' 2>/dev/null
If no PR is found, ask the user to specify one.
Fetch all review comments on the PR (both human and bot/AI):
gh api repos/{owner}/{repo}/pulls/{number}/comments --jq '.[] | {id: .id, path: .path, line: .line, body: .body, user: .user.login, created_at: .created_at}'
Also fetch PR-level review summaries:
gh api repos/{owner}/{repo}/pulls/{number}/reviews --jq '.[] | {id: .id, user: .user.login, state: .state, body: .body}'
Also fetch issue-level comments (used by AI reviewers like CodeRabbit):
gh api repos/{owner}/{repo}/issues/{number}/comments --jq '.[] | {id: .id, body: .body, user: .user.login, html_url: .html_url, created_at: .created_at}'
Fetch review thread IDs for resolving conversations later (GraphQL):
cat <<'GRAPHQL' | gh api graphql --input -
{"query": "query($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $number) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 1) { nodes { databaseId } } } } } } }", "variables": {"owner": "{owner}", "repo": "{repo}", "number": {number}}}
GRAPHQL
Map each databaseId (= REST comment ID) to its GraphQL threadId for the resolve step.
Include all reviewers — human teammates and AI bots alike. Do NOT filter by user type. Track each comment's source type (review comment vs. issue comment) for the reply and resolve steps.
For each review comment:
| Category | Criteria | |----------|----------| | Valid | Real bug, security issue, or meaningful improvement | | Debatable | Stylistic preference or trade-off that could go either way | | Can Safely Ignore | Misunderstands the code, already handled elsewhere, or not applicable |
Group findings by category and present to the user:
## Review Analysis for PR #{number}
Reviewers: {reviewer names joined by " · "}
Comments: ✅ {valid_count} valid · 🤔 {debatable_count} debatable · ❌ {ignore_count} ignored
────────────────────
### < ✅ Valid Suggestions ({n}) >
---
**V1. [{file}:{line}]** {summary}
- Reviewer ({reviewer_name}): {brief quote}
- Assessment: {why this is valid, what the fix should be}
---
**V2. [{file}:{line}]** {summary}
- Reviewer ({reviewer_name}): {brief quote}
- Assessment: {why this is valid, what the fix should be}
────────────────────
### < 🤔 Debatable ({n}) >
---
**D1. [{file}:{line}]** {summary} **(추천: {Apply | Won't Fix | Follow-up})**
- Reviewer ({reviewer_name}): {brief quote}
- Pros: {benefits of applying}
- Cons: {reasons to skip}
- Recommendation: {1-line reasoning for the recommendation}
---
**D2. [{file}:{line}]** {summary} **(추천: {Apply | Won't Fix | Follow-up})**
- Reviewer ({reviewer_name}): {brief quote}
- Pros: {benefits of applying}
- Cons: {reasons to skip}
- Recommendation: {1-line reasoning for the recommendation}
────────────────────
### < ❌ Can Safely Ignore ({n}) >
---
**X1. [{file}:{line}]** {summary}
- Reviewer ({reviewer_name}): {brief quote}
- Why: {reason this is not applicable — e.g., misunderstood context, project convention differs}
---
**X2. [{file}:{line}]** {summary}
- Reviewer ({reviewer_name}): {brief quote}
- Why: {reason}
Use bold paragraphs with category prefix (**V1. ...**, **D1. ...**, **X1. ...**) instead of numbered lists so that blank lines between items render correctly in terminal. Prefixes: V = Valid, D = Debatable, X = Ignore. Each category numbers independently (V1, V2, …; D1, D2, …; X1, X2, …).
Three-level visual hierarchy: ──────────────────── (Unicode thin × 20) between categories, --- between items within the same category, blank lines within items.
Category headers use ### < {icon} Category ({n}) > format with count.
Omit categories that have 0 items.
For each Valid or Debatable suggestion:
fix: 리뷰 피드백 반영).After the commit is created, reply to each review comment on GitHub to record the resolution.
For each comment that was discussed (Valid, Debatable, or Ignored), reply using the appropriate API based on the comment's source type:
For review comments (inline file comments):
gh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies -f body="{reply_body}"
For issue comments (CodeRabbit, etc.):
gh api repos/{owner}/{repo}/issues/{number}/comments -f body="{reply_body}"
For issue comments only, prepend a quote line before the structured format: > Re: @{user} [{comment_url}]
This quote line is part of the format for issue comments — it does not apply to review comments.
Replies MUST follow the exact structured format below. Do NOT use free-form prose or unstructured sentences.
Write the reply body in the language configured in the project's CLAUDE.md. If no language is configured, follow the user's conversational language. Examples below are in Korean:
If applied:
✅ **반영 완료**
- **커밋**: [{short_sha}](https://github.com/{owner}/{repo}/commit/{short_sha})
- **변경**: {1-line summary of what was changed}
If Won't Fix:
⏭️ **미반영 (Won't Fix)**
- **사유**: {concise reason — e.g., 프로젝트 컨벤션과 상충, 이미 다른 방식으로 처리됨}
If Follow-up:
🔜 **후속 작업 예정**
- **사유**: {concise reason — e.g., 현재 PR 범위 밖, 별도 작업으로 진행 예정}
- **이슈**: #{issue_number}
If no blanket approval was given, present all planned replies for approval before posting. A blanket instruction (e.g., "모두 반영", "다 적용해", "apply all") covers all remaining steps — code changes, replies, and thread resolution — so do not re-ask per step.
After posting replies, resolve the conversation thread using the GraphQL API:
cat <<'GRAPHQL' | gh api graphql --input -
{"query": "mutation($id: ID!) { resolveReviewThread(input: {threadId: $id}) { thread { isResolved } } }", "variables": {"id": "{thread_id}"}}
GRAPHQL
Use the databaseId → threadId mapping collected in Step 1.
| Disposition | Resolve? | Reason | |-------------|:--------:|--------| | ✅ Applied | Yes | Work is complete | | ⏭️ Won't Fix | Yes | Decision is final, no further action | | 🔜 Follow-up | No | Open work remains — issue tracks it |
Resolve MUST happen immediately after posting the reply for each concluded thread. Do NOT skip this step. Issue comments (CodeRabbit, etc.) do not have resolvable threads — skip the resolve step for those.
If there are Follow-up items from Step 4, group related ones and create a consolidated issue. Do NOT create issues for Won't Fix items — their reasons are already recorded in the PR reply.
gh issue create --title "[Review] PR #{number} 후속 작업" --body "$(cat <<'EOF'
PR #{number} 리뷰에서 확인된 후속 작업 항목.
### 1. {summary}
- 원본: {comment_url}
- 사유: {why deferred}
### 2. {summary}
- 원본: {comment_url}
- 사유: {why deferred}
EOF
)"
Important:
tools
Create a pull request following project conventions. TRIGGER when: user asks to create/open a PR, push and create PR, or any workflow that includes PR creation (e.g., "PR 올려줘", "푸시하고 PR 만들어줘", "commit, push, and create PR"). DO NOT TRIGGER when: user is viewing or listing existing PRs, or performing git operations without PR intent.
documentation
Create a GitHub issue following project conventions with auto-labeling. TRIGGER when: user asks to create an issue, report a bug, request a feature, file a ticket, or track work (e.g., "이슈 만들어줘", "버그 리포트", "feature request", "이거 이슈로 만들어줘"). DO NOT TRIGGER when: user is viewing, listing, or commenting on existing issues without intent to create a new one.
development
Generate a copy-ready handoff prompt for transferring work context to a new session. TRIGGER when: user asks to hand off work, create a handoff prompt, transfer context, wrap up session, prepare for next session (e.g., "handoff 해줘", "다음 세션으로 넘겨줘", "작업 이관해줘", "handoff prompt 만들어줘"). DO NOT TRIGGER when: user is committing, creating PRs, reviewing code, or performing other git operations without handoff intent.
testing
Create a git commit following project conventions. TRIGGER when: user asks to commit, create a commit, stage and commit, save changes, or any workflow that includes committing (e.g., "commit and push", "commit and create PR", "커밋해줘", "커밋하고 푸시"). DO NOT TRIGGER when: user is only checking git status/diff without intent to commit.