From make-no-mistakes
Cross-references open PRs across all repos in the current org with Linear issues, checks Greptile review scores, forces mergeable calculation, and generates an actionable report with merge/rebase/fix recommendations. Use when the user asks "show me open PRs", "what PRs need attention", "review PRs", "check Greptile scores", "what's ready to merge", or wants a comprehensive PR status overview. Do NOT trigger for: creating PRs, code review, or single PR inspection.
npx claudepluginhub dojocodinglabs/make-no-mistakes-toolkit --plugin make-no-mistakesThis skill uses the workspace's default tool permissions.
Execute the following steps to generate a comprehensive review of open PRs and their associated Linear issues. This command also forces GitHub's mergeable calculation and validates Greptile review scores.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Execute the following steps to generate a comprehensive review of open PRs and their associated Linear issues. This command also forces GitHub's mergeable calculation and validates Greptile review scores.
claude /make-no-mistakes:review-open-prs # All repos in the current org
claude /make-no-mistakes:review-open-prs my-repo # Filter to a specific repo
claude /make-no-mistakes:review-open-prs mine # Only PRs authored by me
Detect the GitHub organization dynamically. Try these methods in order:
Method A — Infer from the current repo:
ORG=$(gh repo view --json owner --jq '.owner.login' 2>/dev/null)
Method B — Read from linear-setup.json if it exists at the repo root:
ORG=$(cat linear-setup.json 2>/dev/null | jq -r '.github.org // empty')
Method C — If neither works, ask the user which org to scan.
Once the org is known, discover repositories:
REPOS=$(gh repo list "$ORG" --limit 50 --json name --jq '.[].name')
Also read the issue prefix from linear-setup.json if available:
TEAM_PREFIX=$(cat linear-setup.json 2>/dev/null | jq -r '.team.key // empty')
If TEAM_PREFIX is empty, infer it from the Linear issues fetched in Step 1 (use the most common prefix).
Store ORG, REPOS, and TEAM_PREFIX for use in subsequent steps.
Use the mcp__linear-server__list_issues tool to fetch all issues assigned to "me" that are in active states (not Done, not Cancelled). Use includeArchived: false and limit: 100.
Store the results mentally — you'll need issue identifiers (e.g., {TEAM_PREFIX}-123), titles, states, priorities, and branch names.
For each repo discovered in Step 0, run:
for repo in $REPOS; do
echo "=== $repo ==="
gh pr list --repo "$ORG/$repo" --state open --json title,number,url,headRefName,author,updatedAt,isDraft --limit 50 2>/dev/null
done
If the user provided arguments, filter by those criteria:
$ARGUMENTS may contain a repo name (filter to that repo), a team name (filter Linear issues by team), or "mine" (filter PRs authored by me).GitHub calculates mergeability lazily — it only computes when requested. Force the calculation on ALL my open PRs by querying each one:
# First pass: trigger calculation on all my PRs
for pr_number in <list of my PR numbers>; do
gh pr view "$pr_number" --repo "$ORG/<repo>" --json number,mergeable --jq '{number, mergeable}' 2>/dev/null &
done
wait
After the first pass, collect any PRs that returned mergeable: "UNKNOWN". Wait 5 seconds, then retry those:
sleep 5
# Second pass: retry UNKNOWN ones
for pr_number in <UNKNOWN PR numbers>; do
gh pr view "$pr_number" --repo "$ORG/<repo>" --json number,mergeable --jq '{number, mergeable}' 2>/dev/null
done
If any still return UNKNOWN after the second pass, mark them as "calculating" in the report.
For each of my open PRs, extract BOTH the Greptile confidence score AND the review state:
4a. Get the review state (COMMENTED vs CHANGES_REQUESTED):
for pr_number in <list of my PR numbers>; do
state=$(gh api "repos/$ORG/<repo>/pulls/$pr_number/reviews" \
--jq '[.[] | select(.user.login | test("greptile"; "i")) | .state] | last' 2>/dev/null)
echo "PR #$pr_number: $state"
done
4b. Get the confidence score and Path to 5/5:
for pr_number in <list of my PR numbers>; do
echo "=== PR #$pr_number ==="
# Greptile posts as greptile-apps[bot] in issue comments (not PR review comments)
gh api "repos/$ORG/<repo>/issues/$pr_number/comments" \
--jq '.[] | select(.user.login | test("greptile"; "i")) | .body' 2>/dev/null
done
Parse the score from the HTML tag: <h3>Confidence Score: X/5</h3>
Parse the improvement suggestions from the section: ### Path to 5/5 Confidence (everything between that heading and the next heading or end of comment).
Classify each PR:
For each of my open PRs, get the full check status:
for pr_number in <list of my PR numbers>; do
echo "=== PR #$pr_number ==="
gh pr view "$pr_number" --repo "$ORG/<repo>" \
--json statusCheckRollup --jq '[.statusCheckRollup[] | select(.name != null) | {name, status, conclusion}]' 2>/dev/null
done
Match PRs to Linear issues by:
{TEAM_PREFIX}-123-feature-name, user/{TEAM_PREFIX}-123-slug, or user/{TEAM_PREFIX}-123-impl. Match the issue identifier pattern (team prefix + number, case-insensitive) in the PR's headRefName.Classify each PR into one of these categories:
For each PR that matches one of my Linear issues, use mcp__linear-server__get_issue to get:
includeRelations: true)Present the report in this format:
PRs where: all CI green + mergeable=MERGEABLE + Greptile (4/5 or 5/5) + review state is NOT CHANGES_REQUESTED:
PR #number — Title
Greptile: X/5 (COMMENTED) | Mergeable: MERGEABLE | CI: all green
Linear: ISSUE-ID (State, Priority)
URL
PRs with Greptile score < 5/5 but NOT blocked by other issues. For each, show the "Path to 5/5" items:
PR #number — Title — Greptile: X/5
Path to 5/5:
- [ ] item 1 from Greptile
- [ ] item 2 from Greptile
CI: status | Mergeable: status
URL
PRs where Greptile's review state is CHANGES_REQUESTED (blocking review). These MUST be addressed before merge regardless of score:
PR #number — Title — Greptile: X/5 (CHANGES_REQUESTED)
Greptile feedback summary: key concerns from the review
URL
PRs where mergeable=CONFLICTING:
PR #number — Title
Conflict with: identify likely conflicting PR if possible (e.g., same domain/files)
URL
PRs with any check conclusion=FAILURE:
PR #number — Title
Failed checks: list of failed check names
URL
List assigned issues that have NO matching open PR (these may need attention):
[PRIORITY] ISSUE-ID: Issue Title — State
Group remaining PRs by repository, showing:
repo-name
#number — Title (author, updated X ago) — URL
Note: Do NOT include subtotals next to repo names or a summary dashboard. Keep the report clean and actionable.
After generating the report, ALWAYS send a summary to the user via Slack MCP using mcp__claude_ai_Slack__slack_send_message. This is NOT optional — it happens automatically as part of the command execution. Do NOT ask the user whether to send it.
Send the message to the user's configured status channel. If linear-setup.json contains a slack.statusChannel field, use that channel. Otherwise, ask the user which channel to send to on the first run, then remember it for the session.
The message uses the Slack Report Format defined in Step 9 below. Include ALL open PRs across the org (not just mine), grouped by repo, in the section order: Merged > CI Failures > Merge Conflicts. If no PRs were merged this session, omit the Merged section.
After generating the report, present a numbered action plan. Each action is a concrete batch operation the user can approve or skip. Use the exact PR numbers and repos from the data collected above.
List every PR from "Ready to Merge" as a batch merge command. Present them in dependency order (if PR A's branch was cut from PR B's branch, merge B first). If no dependencies, order by PR number ascending.
The following PRs have all CI green, are mergeable, and Greptile 4/5+:
repo#number — Title
repo#number — Title
...
Shall I merge all of them now? (yes/no/pick)
If the user says "yes", execute for each PR:
gh pr merge <number> --repo "$ORG/<repo>" --squash --delete-branch
If the user says "pick", ask which ones to merge.
Slack Report Format (sent automatically):
Header: :github-pr: *Open PR Review - YYYY/MM/DD*
Sections (in this exact order, per repo, separated by ---):
:github-merged: Merged — PRs that were merged during this session (Action 1 results):github-actions-failure: CI Failures — PRs with failing checks:github-closed: Merge Conflicts — PRs that need rebaseEach PR entry uses 3 levels of - (regular dash, NOT unicode bullets):
- :github-pr: <PR_URL|PRXXX> | <@SLACK_USER_ID> | Title
- `branch-name` · :status_emoji: Status | :ci_emoji: CI · :greptile: X/5
- *RECOMMENDATION:* Actionable recommendation
Rules:
:github-merge-approved: *Pending merge* section:github-merged: (not :merged:) for merge-related headers<https://linear.app/{LINEAR_WORKSPACE}/issue/{ISSUE_ID}|{ISSUE_ID}>•, ◦, ▪) — use - at all levelsList every PR from "Merge Conflicts / Needs Rebase":
The following PRs have merge conflicts:
repo#number — Title (likely conflicts with #other)
...
Shall I rebase them against the base branch? (yes/no/pick)
If the user says "yes", for each conflicting PR:
Smart suggestions: When a conflicting PR also has CI failures, or is part of a dependency chain where another PR has CI failures, proactively suggest "rebase + fix" as a combined option instead of presenting them as separate actions. Example: "PR #X has a merge conflict AND #Y (its dependency) has CI failures. Shall I rebase + fix both? (rebase+fix / rebase-only / skip)"
List every PR from "CI Failures":
The following PRs have failing checks:
repo#number — Title
Failed: check-name-1, check-name-2
...
Shall I investigate and fix the failures? (yes/no/pick)
If the user says "yes", for each PR:
gh run view <run-id> --repo "$ORG/<repo>" --log-failedList every PR where Greptile left CHANGES_REQUESTED:
The following PRs are blocked by Greptile review:
repo#number — Title — Greptile: X/5
Key concerns: summary of Greptile feedback
...
Shall I address the Greptile feedback? (yes/no/pick)
If the user says "yes", for each PR:
Only if there are PRs with Greptile 4/5 or below (but COMMENTED, not CHANGES_REQUESTED), and the user wants to improve them:
The following PRs could be improved to 5/5:
repo#number — Title — Greptile: X/5
- [ ] improvement item 1
- [ ] improvement item 2
...
Want me to address these to reach 5/5? (yes/no/pick)
IMPORTANT — ROUND-BY-ROUND INTERACTION: Present actions ONE AT A TIME. After displaying each action, STOP and wait for the user's response (yes/no/pick/skip) before presenting the next action. Never dump all actions at once. This mirrors the brainstorming skill's conversational style — each round is a single decision point. If the user says "yes", execute that action, report the result, then present the next action. If the user says "skip" or "no", move to the next action immediately. Never auto-merge, auto-rebase, or auto-fix without explicit user approval.
IMPORTANT — VERIFY BEFORE ACTING: Before investigating or fixing any PR (CI failures, merge conflicts, Greptile feedback), always verify the PR is still open first using gh pr view. PRs may have been merged or closed in a different session. If a PR is already MERGED or CLOSED, skip it silently and move to the next one. Do not ask the user to confirm state you can check yourself.
greptile-apps[bot], NOT from PR review bodies (which are empty)<h3>Confidence Score: X/5</h3>### Path to 5/5 Confidencerepos/{owner}/{repo}/pulls/{number}/reviews — filter by greptile-apps[bot], take the LAST review state--squash --delete-branch targeting the default branch (read from linear-setup.json git.baseBranch or detect via gh repo view --json defaultBranchRef)