skills/pr/SKILL.md
Creates or updates a pull request (GitHub) or merge request (GitLab) for the current branch using the Conventional PR format — intent, summary, changes, rationale, and test plan. Captures the implementation conversation's intent into the PR description when run in the same session. Use when a branch is ready for review, or to update an existing PR/MR description.
npx skillsauth add oprogramadorreal/optimus-claude skills/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.
Create or update a PR (GitHub) or MR (GitLab) for the current branch using the Conventional PR format. Detects the hosting platform, checks for an existing PR/MR, and either creates a new one or offers to update the existing one. New PRs target the repository's default branch; updates to existing PRs use the PR's current target branch. PRs/MRs are created as ready to merge (not draft).
Read $CLAUDE_PLUGIN_ROOT/skills/init/references/multi-repo-detection.md for workspace detection. If a multi-repo workspace is detected, run the multi-repo selection procedure below. Otherwise, skip to Verify git state.
git -C <repo-path> rev-parse --abbrev-ref HEAD$CLAUDE_PLUGIN_ROOT/skills/pr/references/default-branch-detection.md (run inside the repo)git -C <repo-path> log --oneline origin/<default-branch>..HEAD 2>/dev/null | head -1<repo> — skipping") and exclude it from the candidates listAskUserQuestion — header "Multi-Repo PRs", question "Multiple repositories have changes ready for PRs:". Options:
<repo> only"git rev-parse --is-inside-work-tree. If not → inform the user and stop.git rev-parse --abbrev-ref HEAD.$CLAUDE_PLUGIN_ROOT/skills/pr/references/default-branch-detection.md. If no default branch can be determined → inform the user: "Could not detect the default branch. Ensure origin is configured and has been fetched." Stop. If on the default branch → inform the user: "You're on the default branch (<branch>). Switch to a feature branch first." Stop.When processing multiple repos, show a heading (e.g., ## repo-name) before starting this step for each repo.
Read $CLAUDE_PLUGIN_ROOT/skills/pr/references/platform-detection.md and use the Platform Detection Algorithm section. If platform is unknown → inform the user that the hosting platform could not be determined and stop.
Read $CLAUDE_PLUGIN_ROOT/skills/pr/references/platform-detection.md and use the CLI Verification section to check availability and authentication. If the CLI is not installed, use the CLI Installation section — offer to install via AskUserQuestion (header "Install CLI", question "The [GitHub CLI (gh) / GitLab CLI (glab)] is required but not installed. Install it now?"):
If the user chooses Cancel → provide manual installation instructions and stop.
If installation fails → provide manual installation instructions and stop.
If installed but auth fails → inform the user: "CLI installed. Run [gh/glab] auth login to authenticate, then re-run /optimus:pr." Stop.
Check if the branch has been pushed: git ls-remote --heads origin <branch> 2>/dev/null
If the branch is not on the remote:
git log --oneline HEAD --not --remotes 2>/dev/null | head -1. If no commits → inform the user: "No commits on this branch yet. Commit your changes first." Stop.git push -u origin <branch>If the branch is on the remote but has unpushed commits (git log origin/<branch>..HEAD --oneline), push them: git push origin <branch>
GitHub: gh pr view --json number,state,title,body,url,baseRefName 2>/dev/null
baseRefName as the PR's target branch, then go to Step 6 (Update Flow)GitLab: glab mr view --output json 2>/dev/null
target_branch from the JSON as the MR's target branch, then go to Step 6 (Update Flow)gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'Collect information about the changes on the branch:
# Commit list
git log --oneline origin/<default-branch>..HEAD
# Changed files summary
git diff --stat origin/<default-branch>..HEAD
# Full diff for analysis
git diff origin/<default-branch>..HEAD
If there are no commits ahead of the default branch → inform the user: "This branch has no changes compared to <default-branch>." Stop.
Before generating PR content, determine whether author intent is recoverable. This classification drives whether the ## Intent section is populated, preserved, prompted for, or omitted. Classify into one of three states:
git diff --stat origin/<default-branch>..HEAD.## TDD Summary block from /optimus:tdd Step 9 — detected by the literal headings ## TDD Summary and ### Behaviors Implemented (case-sensitive) above the diff, optionally with a ### Coverage section containing Before:, After:, and Delta: lines — treat this as a strong state-1 signal and apply the summary population rule below when filling the PR body.## Implementation Summary block from /optimus:workflow Step 6 — detected by the literal headings ## Implementation Summary and ### Components Built (case-sensitive) above the diff, optionally with a ### Coverage section containing Before:, After:, and Delta: lines — treat this as a strong state-1 signal and apply the summary population rule below when filling the PR body.## Intent section. Detection: see $CLAUDE_PLUGIN_ROOT/skills/pr/references/pr-template.md "Detecting ## Intent in an existing PR body" for the canonical heuristic (shared with /optimus:code-review).State 3 handling — use AskUserQuestion — header "Intent capture", question "No implementation context detected for this branch. How would you like to handle the ## Intent section?":
/optimus:pr from the conversation where the implementation happened.Suppress this prompt entirely in state 1 or state 2 (no friction on the happy paths).
Read the Conventional PR template: $CLAUDE_PLUGIN_ROOT/skills/pr/references/pr-template.md
Generate a title and body following the template. When filling in the sections:
Populate the ## Intent section based on the classification above (state 2 only applies in the Update Flow — Step 6 handles it):
Intent Mismatch findings in /optimus:code-review.Summary population rule — when a TDD or Workflow handoff signal fired during intent detection, populate the body from the summary block visible in the conversation. Both handoffs share one rule; only these per-source tokens differ:
| Handoff | Summary block | Table | Non-goals rows | Key decisions source |
|---------|---------------|-------|----------------|----------------------|
| TDD | ## TDD Summary | ### Behaviors Implemented | Status Not started | refactor-step reasoning captured in the conversation (e.g. "renamed X to match existing pattern", "extracted Y to share with Z") |
| Workflow | ## Implementation Summary | ### Components Built | Status begins with Deferred (include the stated reason) | the ### Stats Orchestration line plus any design choices the summary surfaced (e.g. "fanned out by component, then one integration pass") |
Using the row for whichever handoff fired, fill the PR body:
## Intent → Scope: one bullet per Table row where Status is ✓ Complete, using the description column verbatim.## Intent → Non-goals: one bullet per Table row whose Status matches the Non-goals rows column above. Omit the sub-field if no such rows exist.## Intent → Key decisions: pull from the Key decisions source above. If none are present (e.g. every TDD refactor step reported "No changes needed — code is clean"), omit this sub-field rather than inventing decisions.## Intent → Problem: as specified in the state 1 rules above — quote/summarize the spec or JIRA task file if it was loaded in the conversation, otherwise summarize the initiating brief from the start of the session.## Test plan: one verification item per Table row that is ✓ Complete, plus the project's test command. If the conversation contains a ### Coverage section with Before:, After:, Delta: lines, append a single line Coverage: <Before> → <After> (<Delta>) to the Test plan.Synthesize the Summary from commit messages, changed files, and the diff
Use git diff --stat output as a starting point for Changes, then describe what each file change accomplishes
For the Test plan, look for: test files in the diff → "Run <test command> to verify"; CI configuration → "CI pipeline will run automatically"; manual verification → describe what to check
Present the generated title and body to the user (in a multi-repo workspace, include the repo name in the header):
## PR Preview [— repo-name]
**Title:** <title>
---
<body>
Use AskUserQuestion — header "PR preview", question "Review the PR/MR title and description above. Proceed or adjust?":
If the user chooses Adjust, ask what to change, apply modifications, and preview again.
Write the body to a temp file in the current working directory: TMPFILE=$(mktemp ./pr-body-XXXXXX.md). Clean up after the creation attempt: rm -f "$TMPFILE". (Use a relative path, not /tmp — on Windows, Git Bash's /tmp mount is unresolvable by the native gh.exe/glab.exe, which would silently submit an empty body.)
gh pr create --title "<title>" --body-file "$TMPFILE" --base <default-branch>glab mr create --title "<title>" --description "$(cat "$TMPFILE")" --target-branch <default-branch>Proceed to Step 7.
Display the current title and body to the user:
## Existing PR/MR
**#<number>:** <title>
**URL:** <url>
---
<current body>
Use AskUserQuestion — header "Update PR", question "A PR/MR already exists for this branch. What would you like to do?":
## Intent is preserved verbatim."## Intent is preserved verbatim."## Intent section (or add one if missing). Use when the implementation scope has changed and the existing Intent is stale. Keeps title, Summary, Changes, and Test plan untouched unless they explicitly contradict the new Intent."If the user chooses Cancel → report the existing PR/MR URL and stop.
If the user chooses Regenerate Intent only → re-detect intent context but treat state 2 (existing PR Intent) as replaceable — the user explicitly asked to regenerate it. Populate the new ## Intent from the highest available signal: state 1 (conversation context) when present, otherwise prompt the user directly for Problem / Scope / Non-goals / Key decisions via a plain-message reply (do NOT re-emit the state-3 "How would you like to handle Intent?" meta-prompt — the user has already opted in). If the user provides no reply or all sub-fields are blank, leave the existing Intent unchanged, report "No replacement Intent provided — existing ## Intent kept as-is. No changes will be made.", and stop (do not enter Phase 3). Otherwise replace the ## Intent section in the existing body with the freshly populated one (or insert it before ## Summary if missing). Skip Phase 1 (do not regenerate other sections) and Phase 2 (no preservation pass needed). Jump to Phase 3 (preview).
Gather change data using the existing PR/MR's target branch (saved in Step 4) as the base for diffs — use it in place of <default-branch> in the git log, git diff --stat, and git diff commands from Step 5. Generate new content following the Conventional PR template. This is the authoritative content. Do not present yet.
Review the existing PR/MR title and body (saved from Step 4) for information that cannot be derived from code changes. Examples: issue/ticket references (#45, JIRA-123), deployment instructions, external links, reviewer-directed notes, follow-up tasks, and the ## Intent section.
Never preserve facts that are derivable from the current diff — version numbers, file counts, function/class/symbol names, path names, line counts, or changed-file lists. These must come from Phase 1's fresh content. If the existing body contains such a fact (for example, "plugin version incremented from 1.56.1 to 1.59.0"), discard the old value and use the one re-derived from the current diff, even if the old value was correct when the PR was first opened. Rebases and force-pushes can change any of these, so the description must always match what reviewers see in "Files changed".
Discard anything that is outdated, factually wrong based on current diffs, or already covered by the freshly generated content. If useful non-diff information is found:
## Intent section (load-bearing handoff to /optimus:code-review) — if the existing body has an ## Intent section, always preserve it verbatim and re-insert it at the top of the new body (before ## Summary), matching the template's section order. This is the most critical preservation in the Update Flow: a fresh-conversation update run (no implementation context — e.g., refreshing the PR after a rebase) has no way to recover the original intent, so a silent overwrite would destroy the only record. Never silently overwrite an existing ## Intent section with a fresh inference from commits/diff. If both an existing ## Intent AND a populated conversation context exist, the existing section wins by default; surface a one-line note in the Phase 3 preview — "Existing ## Intent section preserved. The current conversation suggests possible updates — choose 'Regenerate Intent only' if you want to revise." — and continue.## Deployment notes, ## Related issues) that contain non-diff information still relevant, preserve them after ## Test plan.Friction floor for the standalone-update flow: if the existing body has an ## Intent section AND the conversation has no implementation context (no Edit/Write/NotebookEdit touching the current diff), the regeneration must succeed without prompting the user. The user came here to fix the description after a rebase, not to re-litigate intent.
Present the final content for preview. If any non-diff information was carried over from the existing PR/MR, add a brief note above the preview: "Note: some manually-added content from the existing PR/MR was carried over (issue references, deployment notes, etc.)."
Use AskUserQuestion — header "Update preview", question "Review the updated PR/MR. Proceed or adjust?":
Write the body to a temp file (same pattern as Step 5). Clean up after the update attempt.
gh pr edit <number> --title "<title>" --body-file "$TMPFILE" (or --body-file only if keeping the title)glab mr update <number> --title "<title>" --description "$(cat "$TMPFILE")"Proceed to Step 7.
## PR/MR [Created / Updated] [— repo-name]
- URL: [PR/MR URL]
- Title: [title]
- Target: [target-branch]
- Status: Ready to merge
If processing multiple repos, continue to the next repo — go back to Step 2 for the next repo in the list. Do NOT show next-step recommendations or the fresh-conversation tip until all repos are done. After the last repo (or if processing a single repo), proceed to Step 8.
In a multi-repo workspace where multiple repos were processed, show a combined summary across all repos:
## All PRs/MRs Created
| Repo | PR/MR | URL |
|------|-------|-----|
| `repo-name` | title | URL |
Recommend running /optimus:code-review for quality review before merging.
Tell the user the closing tip per $CLAUDE_PLUGIN_ROOT/references/skill-handoff.md "Closing tip wording" — use Variant C (default — /optimus:code-review is non-continuation).
development
Iterative test-coverage improvement loop — dispatches `/optimus:unit-test` (unit-test phase) and `/optimus:refactor` with testability focus (refactor phase) into fresh subagent contexts per cycle, applies tests, runs the test suite, bisects refactor failures, and continues until coverage plateaus or the cycle cap (default 5, hard cap 10). Use to drive coverage up on a codebase that has untestable barriers — the loop alternates between writing tests and unblocking testability so a single skill cannot stall.
development
Iterative project-wide refactoring — runs `/optimus:refactor` in a fresh subagent context per iteration, applies fixes, runs tests, bisects failures, and continues until convergence or the iteration cap (default 8, hard cap 20). Supports `testability` or `guidelines` focus to prioritize finding categories. Each iteration runs in an isolated subagent so context does not accumulate. Requires a test command in .claude/CLAUDE.md. Use for thorough guideline alignment or testability cleanup before /optimus:unit-test.
development
Iterative auto-fix code review — runs `/optimus:code-review` in a fresh subagent context per iteration, applies fixes, runs tests, bisects failures, and continues until convergence or the iteration cap (default 8, hard cap 20). Each iteration runs in an isolated subagent so context does not accumulate. Requires a test command in .claude/CLAUDE.md. Use when single-pass review leaves issues or for thorough cleanup before a release.
development
Implements an approved spec by having Claude design and run its own Claude Code dynamic workflow (real parallel subagents) — you hand it the goal and constraints, it chooses the orchestration. Test-first is enforced as a quality bar (tests accompany or precede code and the suite is left green), not as supervised Red-Green-Refactor. A peer of /optimus:tdd for spec implementation; prefer it for large or parallelizable specs where one linear pass is slow. Requires /optimus:init and a spec (auto-detects docs/specs/ or docs/jira/, or pass a path). Uses meaningfully more tokens than a normal session. Use when a spec is ready to build and you want fan-out implementation instead of turn-by-turn TDD cycles.