Pull Request / Merge Request
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).
Step 1: Pre-flight
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.
Multi-repo selection
- For each child repo, check:
- Current branch:
git -C <repo-path> rev-parse --abbrev-ref HEAD - Default branch: use the algorithm from
$CLAUDE_PLUGIN_ROOT/skills/pr/references/default-branch-detection.md(run inside the repo) - Whether it has commits ahead of default:
git -C <repo-path> log --oneline origin/<default-branch>..HEAD 2>/dev/null | head -1
- Current branch:
- If default branch detection fails for a repo, warn the user (e.g., "Could not detect default branch for
<repo>— skipping") and exclude it from the candidates list - Filter to repos that are on a non-default branch AND have commits ahead of the default branch
- If no repos have changes → inform the user: "No repositories in this workspace have branches with changes ready for a PR." Stop.
- If one repo has changes → inform the user which repo was detected and proceed to run Steps 2–8 inside that repo's directory
- If multiple repos have changes → present the list and use
AskUserQuestion— header "Multi-Repo PRs", question "Multiple repositories have changes ready for PRs:". Options:- All — "Create PRs for all repos with changes (one at a time)"
- Each individual repo name — "Create PR for
<repo>only"
- If the user selects a specific repo, proceed to run Steps 2–8 inside that repo's directory
- If the user selects All, process each repo with changes through Steps 2–8 sequentially. For each repo: run all commands inside that repo's directory, complete Steps 2–7 fully (including the per-repo report in Step 7), then continue to the next repo. After the last repo, show the combined summary from Step 8
Verify git state
- Confirm the current directory is inside a git repository:
git rev-parse --is-inside-work-tree. If not → inform the user and stop. - Get the current branch:
git rev-parse --abbrev-ref HEAD. - Check that the current branch is not the default branch. Detect the default branch using the algorithm in
$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. Ensureoriginis 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.
Step 2: Platform Detection
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.
Step 3: CLI Availability
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?"):
- Install — "Install automatically (requires [package manager])"
- Cancel — "I'll install it manually"
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.
Step 4: Branch and Existing PR/MR Check
Push branch if needed
Check if the branch has been pushed: git ls-remote --heads origin <branch> 2>/dev/null
If the branch is not on the remote:
- Check for commits:
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. - Push:
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>
Check for existing PR/MR
-
GitHub:
gh pr view --json number,state,title,body,url,baseRefName 2>/dev/null- If a PR exists and is open → save the
baseRefNameas the PR's target branch, then go to Step 6 (Update Flow) - If a PR exists but is closed/merged → treat as no PR (create a new one)
- If no PR exists → go to Step 5 (Create Flow)
- If a PR exists and is open → save the
-
GitLab:
glab mr view --output json 2>/dev/null- If an MR exists and is opened → save the
target_branchfrom the JSON as the MR's target branch, then go to Step 6 (Update Flow) - If an MR exists but is closed/merged → treat as no MR
- If no MR exists → go to Step 5 (Create Flow)
- If an MR exists and is opened → save the
Step 5: Create Flow
Detect default branch
- GitHub:
gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' - GitLab: use the default branch detected in Step 1, or
git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'
Gather change data
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.
Detect intent context
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:
- Intent available from conversation — the current conversation contains implementation context for this branch. Signals:
- Prior Edit / Write / NotebookEdit tool calls in the conversation touched files that appear in
git diff --stat origin/<default-branch>..HEAD. - The conversation discussed design decisions, non-goals, trade-offs, or "decided against" language relative to the changes.
- The conversation explicitly stated the problem being solved or the scope of the change.
- TDD handoff (special case of state 1). When the conversation contains a
## TDD Summaryblock from/optimus:tddStep 9 — detected by the literal headings## TDD Summaryand### Behaviors Implemented(case-sensitive) above the diff, optionally with a### Coveragesection containingBefore:,After:, andDelta:lines — treat this as a strong state-1 signal and apply the TDD population rule below when filling the PR body.
- Prior Edit / Write / NotebookEdit tool calls in the conversation touched files that appear in
- Intent available from existing PR body (Update Flow only — Step 6) — the existing PR body contains an
## Intentsection. Detection: see$CLAUDE_PLUGIN_ROOT/skills/pr/references/pr-template.md"Detecting## Intentin an existing PR body" for the canonical heuristic (shared with/optimus:code-review). - No intent context found — neither of the above. Default classification when in doubt: if the heuristic is uncertain, prefer state 3 over fabricating an Intent section.
State 3 handling — use AskUserQuestion — header "Intent capture", question "No implementation context detected for this branch. How would you like to handle