-
Notifications
You must be signed in to change notification settings - Fork 63
chore: add Claude Code skill for code review #372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f97f9a0
d0d2361
d8cb070
52569c0
f3b5e53
ed780b6
916ccf9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,296 @@ | ||||||||||||||||||
| --- | ||||||||||||||||||
| name: review-code | ||||||||||||||||||
| description: Perform a thorough code review of the current branch or a GitHub PR by number. | ||||||||||||||||||
| argument-hint: [pr-number] [special instructions] | ||||||||||||||||||
| disable-model-invocation: true | ||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| # Review Code Changes | ||||||||||||||||||
|
|
||||||||||||||||||
| Perform a comprehensive code review of either the current branch or a specific GitHub pull request. | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Arguments | ||||||||||||||||||
|
|
||||||||||||||||||
| `$ARGUMENTS` determines the review mode: | ||||||||||||||||||
|
|
||||||||||||||||||
| **PR mode** β first argument is a number: | ||||||||||||||||||
| - `366` β review PR #366 | ||||||||||||||||||
| - `366 focus on the API changes` β review PR #366 with a focus area | ||||||||||||||||||
|
|
||||||||||||||||||
| **Branch mode** β no number, or only instructions: | ||||||||||||||||||
| - *(empty)* β review current branch against `main` | ||||||||||||||||||
| - `compare against develop` β review against a different base | ||||||||||||||||||
| - `focus on the API changes` β review current branch with a focus area | ||||||||||||||||||
|
|
||||||||||||||||||
| Additional instructions work in both modes: | ||||||||||||||||||
| - `be strict about type annotations` | ||||||||||||||||||
| - `skip style nits` | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Step 1: Gather Changes | ||||||||||||||||||
|
|
||||||||||||||||||
| ### If PR mode (argument starts with a number) | ||||||||||||||||||
|
|
||||||||||||||||||
| Run these commands in parallel using `gh`: | ||||||||||||||||||
|
|
||||||||||||||||||
| 1. **PR details**: `gh pr view <number> --json title,body,author,baseRefName,headRefName,state,additions,deletions,changedFiles,commits,url` | ||||||||||||||||||
| 2. **PR diff**: `gh pr diff <number>` | ||||||||||||||||||
| 3. **PR files**: `gh pr diff <number> --name-only` | ||||||||||||||||||
| 4. **PR commits**: `gh pr view <number> --json commits --jq '.commits[].messageHeadline'` | ||||||||||||||||||
| 5. **Existing inline review comments**: `gh api repos/{owner}/{repo}/pulls/<number>/comments --paginate --jq '.[].body'` | ||||||||||||||||||
| 5b. **Existing PR-level reviews** (top-level review bodies from "Review changes"): `gh api repos/{owner}/{repo}/pulls/<number>/reviews --paginate --jq '.[].body'` | ||||||||||||||||||
| 6. **Repo info**: `gh repo view --json nameWithOwner -q '.nameWithOwner'` | ||||||||||||||||||
|
|
||||||||||||||||||
| Then get the PR branch locally for full file access. Prefer a **worktree** so your current branch and uncommitted work are untouched: | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash | ||||||||||||||||||
nabinchha marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
| git fetch origin pull/<number>/head:pr-<number> --force | ||||||||||||||||||
| git worktree add /tmp/review-<number> pr-<number> | ||||||||||||||||||
| # Cleanup when done: git worktree remove /tmp/review-<number> && git branch -D pr-<number> | ||||||||||||||||||
| ``` | ||||||||||||||||||
nabinchha marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
|
||||||||||||||||||
| If worktrees aren't suitable, you can use `gh pr checkout <number>` (this switches your current branch β only if you have no uncommitted work). Run the rest of the review from `/tmp/review-<number>`. | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The fallback should instruct the agent to continue from the repository root:
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: .claude/skills/review-code/SKILL.md
Line: 51
Comment:
**`gh pr checkout` fallback references the wrong working directory**
`gh pr checkout <number>` checks out the PR branch directly into the current repository β it does **not** create any directory at `/tmp/review-<number>`. That path only exists when the worktree approach is used. If an agent follows this fallback path, the instruction to "Run the rest of the review from `/tmp/review-<number>`" will produce a "No such file or directory" error, and every subsequent relative path operation will fail.
The fallback should instruct the agent to continue from the repository root:
```suggestion
If worktrees aren't suitable, you can use `gh pr checkout <number>` (this switches your current branch β only if you have no uncommitted work). Run the rest of the review from the repository root. When done, return to your original branch with `git checkout -`.
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||
|
|
||||||||||||||||||
| If checkout isn't possible (e.g., external fork), use `gh api` to fetch file contents: | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash | ||||||||||||||||||
| gh api repos/{owner}/{repo}/contents/{path}?ref={head-branch} --jq '.content' | base64 --decode | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
Comment on lines
+51
to
+57
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. External-fork fallback condition is inaccurate The comment "If checkout isn't possible (e.g., external fork)" on line 51 and the GitHub exposes a synthetic ref git fetch origin pull/<number>/head:pr-<number> --force
git worktree add /tmp/review-<number> pr-<number>works equally well for same-repo branches and external forks, as long as the PR is open and the runner has network access to An agent reading this skill may skip the efficient worktree path and fall back to slow, per-file The fallback condition should describe the cases where the worktree path genuinely fails (e.g.
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: .claude/skills/review-code/SKILL.md
Line: 51-57
Comment:
**External-fork fallback condition is inaccurate**
The comment "If checkout isn't possible (e.g., external fork)" on line 51 and the `gh api` content-fetch fallback on lines 53β57 are presented as if external forks prevent the primary worktree path from working. That is not the case.
GitHub exposes a synthetic ref `refs/pull/<number>/head` for **every** open PR β including those from external forks β and that ref is fetchable via the upstream `origin` remote. This means:
```bash
git fetch origin pull/<number>/head:pr-<number> --force
git worktree add /tmp/review-<number> pr-<number>
```
works equally well for same-repo branches and external forks, as long as the PR is open and the runner has network access to `origin`.
An agent reading this skill may skip the efficient worktree path and fall back to slow, per-file `gh api` calls for every external-fork PR unnecessarily.
The fallback condition should describe the cases where the worktree path genuinely fails (e.g. `origin` is not a GitHub remote, the PR ref has been garbage-collected after a very old close, or the runner has no `git` access) rather than citing "external fork":
```suggestion
If the worktree approach fails for any reason (e.g. the runner has no direct `git` access to the remote, or the PR ref is no longer available), you can use `gh api` to fetch file contents directly:
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||
|
|
||||||||||||||||||
| **Important checks:** | ||||||||||||||||||
| - If the PR number doesn't exist, inform the user | ||||||||||||||||||
| - If the PR is merged or closed, note the state but proceed (useful for post-merge audits) | ||||||||||||||||||
| - If the PR is a draft, note it β review may be on incomplete work | ||||||||||||||||||
| - For very large diffs (>3000 lines), fetch and read changed files individually instead of relying solely on the diff | ||||||||||||||||||
|
|
||||||||||||||||||
| ### If Branch mode (no number) | ||||||||||||||||||
|
|
||||||||||||||||||
| First, fetch the base branch to ensure the remote ref is current: | ||||||||||||||||||
|
|
||||||||||||||||||
| 0. **Fetch base**: `git fetch origin <base>` | ||||||||||||||||||
|
|
||||||||||||||||||
| Then run these commands in parallel: | ||||||||||||||||||
|
|
||||||||||||||||||
| 1. **Current branch**: `git branch --show-current` | ||||||||||||||||||
| 2. **Commits on branch**: `git log origin/<base>..HEAD --oneline` | ||||||||||||||||||
| 3. **File changes summary**: `git diff --stat origin/<base>..HEAD` | ||||||||||||||||||
| 4. **Full diff**: `git diff origin/<base>..HEAD` | ||||||||||||||||||
| 5. **Uncommitted changes**: `git status --porcelain` | ||||||||||||||||||
| 6. **Merge base**: `git merge-base origin/<base> HEAD` | ||||||||||||||||||
|
|
||||||||||||||||||
| Where `<base>` is `main` unless overridden in arguments. | ||||||||||||||||||
|
|
||||||||||||||||||
| **Important checks:** | ||||||||||||||||||
| - If no commits ahead of base, inform the user there's nothing to review | ||||||||||||||||||
| - If uncommitted changes exist, note them but review committed changes only | ||||||||||||||||||
| - For very large diffs (>3000 lines), read changed files individually instead of relying solely on the diff | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Step 2: Load Project Guidelines | ||||||||||||||||||
|
|
||||||||||||||||||
| Read `AGENTS.md` at the repository root to load the project's coding standards, design principles, and conventions. This is the authoritative source for: | ||||||||||||||||||
|
|
||||||||||||||||||
| - Code style rules (formatting, naming, imports, type annotations) | ||||||||||||||||||
| - Design principles (DRY, KISS, YAGNI, SOLID) | ||||||||||||||||||
| - Testing patterns and expectations | ||||||||||||||||||
| - Architecture and layering conventions | ||||||||||||||||||
| - Common pitfalls to watch for | ||||||||||||||||||
| - Lazy loading and `TYPE_CHECKING` patterns | ||||||||||||||||||
|
|
||||||||||||||||||
| Use these guidelines as the baseline for the entire review. Any project-specific rules in `AGENTS.md` take precedence over general best practices. | ||||||||||||||||||
nabinchha marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
|
||||||||||||||||||
| ## Step 3: Understand the Scope | ||||||||||||||||||
|
|
||||||||||||||||||
| Before diving into details, build a mental model: | ||||||||||||||||||
|
|
||||||||||||||||||
| 1. **Read the PR description** (PR mode) or commit messages to understand the stated intent | ||||||||||||||||||
| 2. **Read each commit message** to understand the progression of changes | ||||||||||||||||||
| 3. **Group changed files** by module/package to identify which areas are affected | ||||||||||||||||||
| 4. **Identify the primary goal** (feature, refactor, bugfix, etc.) | ||||||||||||||||||
| 5. **Note cross-cutting concerns** (e.g., a rename that touches many files vs. substantive logic changes) | ||||||||||||||||||
| 6. **Check existing feedback** (PR mode): inspect both inline comments (Step 1, item 5) and PR-level review bodies (Step 1, item 5b) so you don't duplicate feedback already given | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Step 4: Review Each Changed File (Multi-Pass) | ||||||||||||||||||
|
|
||||||||||||||||||
| Perform **at least 2-3 passes** over the changed files. Each pass has a different focus β this catches issues that a single read-through would miss. | ||||||||||||||||||
|
|
||||||||||||||||||
| **Scope rule: Only flag issues introduced or modified by this changeset.** Read the full file for context, but do not report pre-existing patterns, style issues, or design choices that were already present before this branch/PR. If existing code was merely moved without modification, don't flag it. The goal is to review what the author changed, not audit the entire file. | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Pass 1: Correctness & Logic | ||||||||||||||||||
|
|
||||||||||||||||||
| Read each changed file in full (not just the diff), but evaluate only the **new or modified code**: | ||||||||||||||||||
|
|
||||||||||||||||||
| - Logic errors, off-by-one, wrong operator, inverted condition | ||||||||||||||||||
| - Missing edge case handling (None, empty collections, boundary values) | ||||||||||||||||||
| - Truthy/falsy checks on values where 0, empty string, or None is valid (e.g. `if index:` when index can be 0) | ||||||||||||||||||
| - Defensive `getattr(obj, attr, fallback)` or `.get()` on Pydantic models where the field always exists with a default | ||||||||||||||||||
| - Silent behavior changes for existing users that aren't called out in the PR description | ||||||||||||||||||
| - Race conditions or concurrency issues | ||||||||||||||||||
| - Resource leaks (unclosed files, connections, missing cleanup) | ||||||||||||||||||
| - Incorrect error handling (swallowed exceptions, wrong exception type) | ||||||||||||||||||
| - Input validation at boundaries (user input, API responses, file I/O) | ||||||||||||||||||
| - Graceful degradation on failure | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Pass 2: Design, Architecture & API | ||||||||||||||||||
|
|
||||||||||||||||||
| Re-read the changed files with a focus on **structure and design of the new/modified code**: | ||||||||||||||||||
|
|
||||||||||||||||||
| - Does the change fit the existing architecture and patterns? | ||||||||||||||||||
| - Are new abstractions at the right level? (too abstract / too concrete) | ||||||||||||||||||
| - Single responsibility β does each new function/class do one thing? | ||||||||||||||||||
| - Are new dependencies flowing in the right direction? | ||||||||||||||||||
| - Could this introduce circular imports or unnecessary coupling? | ||||||||||||||||||
| - Are new or modified public signatures clear and minimal? | ||||||||||||||||||
| - Are return types precise (not overly broad like `Any`)? | ||||||||||||||||||
| - Could the new API be misused easily? Is it hard to use incorrectly? | ||||||||||||||||||
| - Are breaking changes to existing interfaces intentional and documented? | ||||||||||||||||||
| - Unnecessary wrapper functions or dead code left behind after refactors | ||||||||||||||||||
| - Scalability: in-memory operations that could OOM on large datasets | ||||||||||||||||||
| - Raw exceptions leaking instead of being normalized to project error types (see AGENTS.md / interface errors) | ||||||||||||||||||
| - Obvious inefficiencies introduced by this change (N+1 queries, repeated computation, unnecessary copies) | ||||||||||||||||||
| - Appropriate data structures for the access pattern | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Pass 3: Standards, Testing & Polish | ||||||||||||||||||
|
|
||||||||||||||||||
| Final pass focused on **project conventions and test quality for new/modified code only**: | ||||||||||||||||||
|
|
||||||||||||||||||
| **Testing:** | ||||||||||||||||||
| - Are new code paths covered by tests? | ||||||||||||||||||
| - Do new tests verify behavior, not implementation details? (Flag tests that only verify plumbing β e.g. "mock was called" β without exercising actual behavior.) | ||||||||||||||||||
| - Duplicate test setup across tests that should use fixtures or `@pytest.mark.parametrize` | ||||||||||||||||||
| - Prefer flat test functions over test classes unless grouping is meaningful | ||||||||||||||||||
| - Are edge cases tested? | ||||||||||||||||||
| - Are mocks/stubs used appropriately (at boundaries, not deep internals)? | ||||||||||||||||||
| - Do new test names clearly describe what they verify? | ||||||||||||||||||
|
|
||||||||||||||||||
| **Project Standards (from AGENTS.md) β apply to new/modified code only:** | ||||||||||||||||||
|
|
||||||||||||||||||
| Verify the items below on lines introduced or changed by this branch. Refer to the full `AGENTS.md` loaded in Step 2 for details and examples. | ||||||||||||||||||
|
|
||||||||||||||||||
| - License headers: if present, they should be correct (wrong year or format β suggest `make update-license-headers`; don't treat as critical if CI enforces this) | ||||||||||||||||||
| - `from __future__ import annotations` in new files | ||||||||||||||||||
| - Type annotations on new/modified functions, methods, and class attributes | ||||||||||||||||||
| - Modern type syntax (`list[str]`, `str | None` β not `List[str]`, `Optional[str]`) | ||||||||||||||||||
| - Absolute imports only (no relative imports) | ||||||||||||||||||
| - Lazy loading for heavy third-party imports via `lazy_heavy_imports` + `TYPE_CHECKING` | ||||||||||||||||||
| - Naming: snake_case functions starting with a verb, PascalCase classes, UPPER_SNAKE_CASE constants | ||||||||||||||||||
| - No vacuous comments β comments only for non-obvious intent | ||||||||||||||||||
| - Public before private ordering in new classes | ||||||||||||||||||
| - Design principles: DRY (extract on third occurrence), KISS (flat over clever), YAGNI (no speculative abstractions) | ||||||||||||||||||
| - Common pitfalls: no mutable default arguments, no unused imports, simplify where possible | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Step 5: Run Linter | ||||||||||||||||||
|
|
||||||||||||||||||
| Run the linter on all changed files (requires local checkout). Use the venv directly to avoid sandbox permission issues in some environments (e.g. Claude Code): | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash | ||||||||||||||||||
| .venv/bin/ruff check <changed-files> | ||||||||||||||||||
| .venv/bin/ruff format --check <changed-files> | ||||||||||||||||||
|
Comment on lines
+184
to
+186
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Step 5 uses Either use the absolute path to the venv or note that the linter should be invoked from the original repo root (not from the worktree):
Suggested change
Alternatively, if Prompt To Fix With AIThis is a comment left during a code review.
Path: .claude/skills/review-code/SKILL.md
Line: 184-186
Comment:
**`.venv/bin/ruff` is a relative path that won't resolve inside the worktree**
Step 5 uses `.venv/bin/ruff` (a relative path). When the agent is working from the worktree at `/tmp/review-<number>`, there is no `.venv` directory there β it lives in the original repository root. The command will fail with "No such file or directory".
Either use the absolute path to the venv or note that the linter should be invoked from the original repo root (not from the worktree):
```suggestion
$(git rev-parse --show-toplevel)/.venv/bin/ruff check <changed-files>
$(git rev-parse --show-toplevel)/.venv/bin/ruff format --check <changed-files>
```
Alternatively, if `uv` is available globally this is avoided entirely with `uv run ruff check <changed-files>`, which discovers the project venv regardless of the current directory.
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||
| ``` | ||||||||||||||||||
nabinchha marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
|
||||||||||||||||||
| > **Note**: This runs ruff only on the changed files for speed. For a full project-wide check, use `make check-all` or `uv run ruff check` (and `ruff format --check`) without file arguments. | ||||||||||||||||||
|
|
||||||||||||||||||
| If the branch isn't checked out locally (e.g., external fork in PR mode), skip this step and note it in the review. | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Step 6: Produce the Review | ||||||||||||||||||
|
|
||||||||||||||||||
| Output a structured review using the format below. Use the **PR template** or **Branch template** for the overview depending on the mode. | ||||||||||||||||||
nabinchha marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
|
|
||||||||||||||||||
| Write the review to a **temporary markdown file outside the repository** (e.g. `/tmp/review-<pr-or-branch>.md`) so other agents or tools can consume it without polluting `git status`. Do not commit this file; treat it as ephemeral. | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Overview (PR mode) | ||||||||||||||||||
|
|
||||||||||||||||||
| | | | | ||||||||||||||||||
| |---|---| | ||||||||||||||||||
| | **PR** | [#\<number\> \<title\>](\<url\>) | | ||||||||||||||||||
| | **Author** | `<author>` | | ||||||||||||||||||
| | **Base** | `<base-branch>` | | ||||||||||||||||||
| | **Files changed** | `<count>` | | ||||||||||||||||||
| | **Insertions/Deletions** | `+<ins> / -<del>` | | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Overview (Branch mode) | ||||||||||||||||||
|
|
||||||||||||||||||
| | | | | ||||||||||||||||||
| |---|---| | ||||||||||||||||||
| | **Branch** | `<branch-name>` | | ||||||||||||||||||
| | **Commits** | `<count>` commits ahead of `<base>` | | ||||||||||||||||||
| | **Files changed** | `<count>` | | ||||||||||||||||||
| | **Insertions/Deletions** | `+<ins> / -<del>` | | ||||||||||||||||||
|
|
||||||||||||||||||
| ### (Both modes) | ||||||||||||||||||
|
|
||||||||||||||||||
| **Summary**: 1-2 sentence description of what the changes accomplish. In PR mode, note whether the implementation matches the stated intent in the PR description. | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Findings | ||||||||||||||||||
|
|
||||||||||||||||||
| Group findings by severity. Format each finding as a heading + bullet list β do NOT use numbered lists: | ||||||||||||||||||
|
|
||||||||||||||||||
| ``` | ||||||||||||||||||
| **`path/to/file.py:42` β Short title** | ||||||||||||||||||
| - **What**: Concise description of the issue. | ||||||||||||||||||
| - **Why**: Why it matters. | ||||||||||||||||||
| - **Suggestion**: Concrete fix or improvement (with code snippet when helpful). | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| Separate each finding with a blank line. Use bold file-and-title as a heading line, then bullet points for What/Why/Suggestion. Never use numbered lists (`1.`, `2.`) for findings or their sub-items β they render poorly in terminals. | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Critical β Must fix before merge | ||||||||||||||||||
| > Issues that would cause bugs, data loss, security vulnerabilities, or broken functionality. | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Warnings β Strongly recommend fixing | ||||||||||||||||||
| > Design issues, missing error handling, test gaps, or violations of project standards that could cause problems later. | ||||||||||||||||||
|
|
||||||||||||||||||
| #### Suggestions β Consider improving | ||||||||||||||||||
| > Style improvements, minor simplifications, or optional enhancements that would improve code quality. | ||||||||||||||||||
|
|
||||||||||||||||||
| ### What Looks Good | ||||||||||||||||||
|
|
||||||||||||||||||
| Call out 2-3 things done well (good abstractions, thorough tests, clean refactoring, etc.). Positive feedback is part of a good review. | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Verdict | ||||||||||||||||||
|
|
||||||||||||||||||
| One of: | ||||||||||||||||||
| - **Ship it** β No critical issues, ready to merge | ||||||||||||||||||
| - **Ship it (with nits)** β Minor suggestions but nothing blocking | ||||||||||||||||||
| - **Needs changes** β Has issues that should be addressed before merge | ||||||||||||||||||
| - **Needs discussion** β Architectural or design questions that need team input | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Next steps (optional) | ||||||||||||||||||
|
|
||||||||||||||||||
| After the summary, you may suggest follow-ups when useful: | ||||||||||||||||||
|
|
||||||||||||||||||
| - Deep dive into a specific file or finding | ||||||||||||||||||
| - Check a specific concern in more detail | ||||||||||||||||||
| - Install dev deps and add smoke tests (e.g. `uv sync --all-extras`, then run tests or suggest minimal smoke tests) | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Review Principles | ||||||||||||||||||
|
|
||||||||||||||||||
| - **Only flag what's new**: Report issues introduced by this changeset β not pre-existing patterns or style in untouched code, unless explicitly asked by the user | ||||||||||||||||||
| - **Be specific**: "This could return None on line 42 when `items` is empty" not "handle edge cases better" | ||||||||||||||||||
| - **Suggest, don't just criticize**: Always pair a problem with a concrete suggestion | ||||||||||||||||||
| - **Distinguish severity honestly**: Don't inflate nits to warnings; don't downplay real issues | ||||||||||||||||||
| - **Consider intent**: Review what the author was trying to do, not what you would have done differently | ||||||||||||||||||
| - **Batch related issues**: If the same pattern appears in multiple places, note it once and list all locations | ||||||||||||||||||
| - **Read the full file**: Diff-only reviews miss context β always read the surrounding code, but only flag new issues | ||||||||||||||||||
| - **Don't repeat existing feedback**: In PR mode, check both inline comments and PR-level review bodies and skip issues already raised | ||||||||||||||||||
|
|
||||||||||||||||||
| **Do not flag (focus on what CI won't catch):** | ||||||||||||||||||
|
|
||||||||||||||||||
| - Issues that are supposed to be caught by CI (linter, typechecker, formatter) β mention "run `make check-all`" if relevant, but don't list every style nit | ||||||||||||||||||
| - Pre-existing issues on unmodified lines | ||||||||||||||||||
| - Pedantic nits that don't affect correctness or maintainability | ||||||||||||||||||
| - Intentional functionality or API changes that are clearly documented | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Edge Cases | ||||||||||||||||||
|
|
||||||||||||||||||
| - **No changes**: Inform user there's nothing to review | ||||||||||||||||||
| - **PR not found**: Inform user the PR number doesn't exist | ||||||||||||||||||
| - **Merged/closed PR**: Note the state, proceed with review anyway | ||||||||||||||||||
| - **Draft PR**: Note it's a draft; review may be on incomplete work | ||||||||||||||||||
| - **External fork**: Can't checkout locally β use `gh api` to fetch file contents and skip the linter step | ||||||||||||||||||
| - **Huge changeset** (>50 files): Summarize by module first, then review the most critical files in detail; ask user if they want the full file-by-file review | ||||||||||||||||||
| - **Only renames/moves**: Note that changes are structural and focus on verifying nothing broke | ||||||||||||||||||
| - **Only test changes**: Focus review on test quality, coverage, and correctness of assertions | ||||||||||||||||||
| - **Only config/docs changes**: Adjust review to focus on accuracy and completeness rather than code quality | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Steps 5/5b depend on step 6's output but all are run in parallel
Steps 5 and 5b contain the literal placeholder
{owner}/{repo}in thegh apiURL, but that value is only available after step 6 (gh repo view --json nameWithOwner) completes. The instruction to run all six commands in parallel means the API calls would be constructed before the owner/repo is known.In practice an LLM agent might infer the remote from the git context, but the skill should make this ordering dependency explicit to avoid silent failures on repos where the remote origin doesn't match the default GitHub host.
Consider sequencing step 6 first (it's instant), then running steps 1β5b in parallel with the owner/repo substituted in:
Prompt To Fix With AI