skills/review-pr/SKILL.md
Comprehensive PR review (product + technical) with optional GitHub inline comments. Use when user asks to "review PR", "review pull request", gives a PR number to review, or says "review #123". Works on any PR state: open, draft, merged, closed. Fetches linked ticket/issue, runs product and technical review, then optionally posts the review with inline comments to GitHub. Do NOT use for reviewing current branch changes (use deep-review skill instead).
npx skillsauth add nicolas-codemate/claudecodeconfig review-prInstall 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.
Comprehensive review of any PR by number. Combines product review (ticket alignment) and technical review (code quality), then optionally posts findings to GitHub as inline comments.
<constraints> - Do not review the code yourself in the current context — confirmation bias is exactly what we're guarding against. - Delegate the actual review to an Agent (`subagent_type: "code-reviewer"`). - The agent prompt must be fully self-contained (all text inline, no file paths to read). - Display the agent's review report verbatim — do not filter or soften findings. - What gets published on GitHub is narrower than the local report: inline comments for defects, and a global summary only for ticket requirements left unaddressed. If the agent returns more than that, strip it before posting. - Do not post to GitHub without explicit user confirmation. - All user communication in French, technical output in English. </constraints>REVIEW_LANG = "fr" (French) — applies to inline comments and the global review summary posted on GitHub--lang en / --lang fr, or signals it naturally ("in english", "en anglais", "review in english")REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
gh pr view $pr_number --json title,state,author,baseRefName,headRefName,body,url,isDraft,labels
gh pr diff $pr_number
PR_TITLE, PR_STATE, PR_BODY, PR_DIFF, PR_BASE, PR_HEAD, PR_URL, REVIEW_LANG/resume:
~/.claude/scripts/rename-session.sh "review-pr-$pr_number - $PR_TITLE"
Substitute the real values inline and single-quote the argument if the title contains
double quotes or backticks. If the script fails, note it and continue — renaming is
never a reason to abort the review.From the PR body and title, detect linked ticket/issue references.
Detection patterns (scan both PR_BODY and PR_TITLE):
/\b[A-Z]+-\d+\b/ (e.g., PROJ-123, ABC-1)/\b(?:closes?|fixes?|resolves?)\s+#(\d+)\b/i, or standalone #(\d+)Resolution — when a reference is found, retrieve the ticket by following the shared procedure:
~/.claude/skills/fetch-ticket/SKILL.md with the Read tool and follow its procedure inline with the detected ID. It is an internal reference file, not an invocable skill — do NOT call the Skill tool on it.mcp__youtrack__get_issue + get_issue_comments, GitHub via gh issue view) and returns normalized markdown with description, status, and commentsFallback chain:
Store the result as TICKET_CONTENT (fetched ticket markdown when available, PR body + title otherwise).
The code-reviewer agent must receive all context inline — it should not need to read any files.
Agent:
subagent_type: code-reviewer
description: "PR review #{pr_number}"
prompt: |
You are reviewing PR #{pr_number}: "{PR_TITLE}".
PR state: {PR_STATE}. Branch: {PR_HEAD} -> {PR_BASE}.
You have NO prior knowledge of this code. Review with fresh eyes.
<ticket_context>
{TICKET_CONTENT}
</ticket_context>
<pr_description>
{PR_BODY}
</pr_description>
<project_conventions>
{PROJECT_RULES from CLAUDE.md}
</project_conventions>
<diff>
{PR_DIFF}
</diff>
Perform a complete code review following your review process.
Return the full review report in markdown format (in English, as usual).
IMPORTANT — budget discipline:
- The diff above is your primary source. Avoid exhaustive codebase exploration;
use Grep/Read only when a specific finding truly requires it.
- The final report (including the JSON block below) is MANDATORY.
Do not run out of turns mid-exploration — finalize the report first,
add supporting exploration only if budget allows.
IMPORTANT: At the end of your review, add a section:
## Inline Comments (for GitHub)
Output a fenced JSON block with this exact structure:
```json
{
"status": "APPROVED" | "COMMENT" | "REQUEST_CHANGES",
"summary": "Multi-section markdown summary (see formatting rules below)",
"comments": [
{
"path": "relative/file/path.ext",
"line": <line_number_in_new_file>,
"body": "Structured markdown comment (see formatting rules below)"
}
]
}
```
Rules for inline comments:
- **Language**: write `summary` and every `body` in {REVIEW_LANG_FULL} (REVIEW_LANG = "{REVIEW_LANG}"). Keep code identifiers, file paths, and technical terms in their original form. Use proper accents when writing in French (é, è, ê, à, ù, ç).
- Only include Critical and Important issues (not Minor/suggestions)
- `line` is the line number in the NEW version of the file (right side of diff)
- `path` is relative to repo root
- If no inline comments needed, use an empty array
- `status`: `REQUEST_CHANGES` on a Critical issue or an unaddressed ticket
requirement, `APPROVED` if nothing reaches the gate below, `COMMENT` otherwise
**Publication gate — what is allowed to reach GitHub:**
Only two kinds of findings may appear in the JSON block:
1. A defect in the changed code: bug, regression, security hole, data loss,
broken contract, or a violation of a rule written in <project_conventions>.
2. A requirement of <ticket_context> that the diff does not implement.
Everything else stays in the local report and never reaches the JSON block:
- Judgements on the project's engineering practices: what deserves a test,
deprecation or compatibility-layer policy, deployment order, branching,
follow-up tickets, PR description quality, commit hygiene.
- Refactor invitations, architecture direction, "consider", "it would be worth".
- Anything you cannot back with a concrete failure case (input or state ->
wrong behaviour) or with an explicit line of the ticket or the conventions.
You do not know how this team works beyond what <project_conventions> and
<ticket_context> state. Inferring a practice from the diff and then asking for
it to change is a failure, worse than missing an issue. A finding is either
firm enough to state as a fact, or it is dropped — no hedging, no nuance.
**`summary` (the global review body) — deliberately minimal:**
- Its ONLY legitimate content is case 2 above: unaddressed ticket requirements.
- No verdict, no strengths, no concerns, no recommendation, no next steps,
no restatement of the inline comments.
- When every requirement is covered, or there is no ticket, `summary` is exactly
this single line and nothing else:
`Review : voir les commentaires inline.` (French) /
`Review: see the inline comments.` (English).
It only exists because GitHub rejects an empty body on `COMMENT` and
`REQUEST_CHANGES`.
- Otherwise `summary` is exactly this block, with no preamble and no closing
sentence (use real `\n\n` blank lines in the JSON string):
```
### Besoins du ticket non traités
- <requirement as written in the ticket> : <what is missing, one line>
```
(English title: `### Unaddressed ticket requirements`)
- One bullet per requirement, one line each, factual, no hedging verb.
`body` structure for each inline comment (use real `\n\n` blank lines in the JSON string):
```
**<Severity tag>** : <one-line problem statement>
<1-2 sentences explaining the impact or root cause>
**Suggestion** : <concrete fix, can include a short code snippet in a fenced block>
```
- Severity tag is `Critical` or `Important` (translated: `Critique` / `Important` in French)
- Always separate the three parts with a blank line — never cram them into a single paragraph
- Use inline code (`` `like_this` ``) for identifiers and short fenced blocks for multi-line suggestions
- Keep the whole body under ~8 lines of rendered markdown; split into multiple comments if needed
Where {REVIEW_LANG_FULL} expands to "French" if REVIEW_LANG = "fr", "English" if REVIEW_LANG = "en".
## Inline Comments sectionsummary down to its allowed form, and drop any inline comment that does not point
at a defect in the diff.Review terminee: {status}
- {N} commentaires inline prets a publier (langue: {REVIEW_LANG})
- Fichiers concernes: {list}
- Commentaire global: {"aucun besoin ticket non traite" | "{N} besoin(s) ticket non traite(s)"}
Ask the user (mention the publication language so they can override before posting):
Publier cette review sur GitHub ? (Commentaires inline + summary seront postes en {REVIEW_LANG_FULL})
- Oui : publier telle quelle
- Modifier : editer avant publication (utile pour changer la langue, ex: "regenere en anglais")
- Non : garder en local uniquement
If the user asks to switch language at this stage, re-run Phase 3 with the new REVIEW_LANG (the rest of the review is unchanged, only the agent re-translates summary + body fields).
If "Oui" or "Modifier":
Construct the review payload. Preserve the multi-line markdown formatting from the
agent's summary and each body — they contain real blank lines (\n\n) that must
survive as JSON string escapes, otherwise GitHub renders them as a single wall of text.
Prefer jq -n for safe escaping rather than hand-written JSON:
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
# Build payload with jq so multi-line strings are escaped correctly.
# Replace the placeholders with the values from the agent's JSON block.
jq -n \
--arg body "$SUMMARY_MARKDOWN" \
--arg event "$STATUS" \
--argjson comments "$COMMENTS_JSON_ARRAY" \
'{body: $body, event: $event, comments: $comments}' \
> /tmp/pr-review.json
# Post the review
gh api "repos/$REPO/pulls/$pr_number/reviews" --input /tmp/pr-review.json
# Cleanup
rm -f /tmp/pr-review.json
If you build the JSON by hand instead, each newline inside summary or body must
be written as the two-character escape \n in the JSON string — never as a raw line
break, which would produce invalid JSON.
Confirm success:
Review publiee sur {PR_URL}
If "Non": End. The review stays in the conversation only.
If the diff exceeds ~50,000 characters, truncate with a note:
(diff tronque a 50000 caracteres, {total} au total - focus sur les fichiers les plus importants)
Review works identically - gh pr diff returns the diff regardless of state.
When posting review comments on merged PRs, GitHub may reject inline comments
if the commit SHA no longer matches. In that case, post as a single conversation
comment instead:
gh api "repos/$REPO/issues/$pr_number/comments" -f body="{full review text}"
Review in "code quality only" mode - the product review section focuses on the PR description and whether the changes are self-explanatory.
REVIEW_LANG
REVIEW_LANG = "fr")--lang en (or --lang fr) when invoking the skill, or signal naturally ("review in english", "en anglais")development
Method to diagnose and raise the Lighthouse performance score of a public page (landing, marketing, home). Use when asked to improve Lighthouse/PageSpeed scores, when auditing the first uncached paint of a public page, or when a landing embedded in a SPA must reach a top score. Do NOT use for in-app screen performance (data loading, rendering). For a brand-new landing, the first recommendation is static HTML with no framework runtime — most of this skill exists for when that is not an option.
tools
Audits a project's Claude Code setup against real usage — mines the project's conversations (worktrees included), confronts the project's skills/agents/CLAUDE.md with best practices, and proposes adjustments or new skills/agents/rules. Use when the user asks to audit the project config, analyze project conversations, or find automation opportunities for the current project. Do NOT use for the global ~/.claude configuration (use /audit-config instead).
development
Coaching workflow orchestrator. Guides the developer through implementation without writing code.
development
Disciplined methodology for code architecture refactoring. Use when the user asks to refactor architecture, decouple code, restructure a family of classes, redesign an interface, or rename/reorganize a set of related components. Forces a big-picture analysis before any code is written. Do NOT use for simple bug fixes, feature additions, or single-file refactoring.