Claude Code Plugins

Community-maintained marketplace

Feedback
4
0

Standard workflow for all PR operations ('create PR', 'open PR', 'pull request', 'commit and PR'): replaces bash-based gh/git workflows with end-to-end orchestration—handles uncommitted changes (auto-invokes creating-commit/creating-branch), analyzes commit history, generates convention-aware content, detects fork/origin. Canonical PR implementation for git-workflows.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md


name: creating-pull-request description: Standard workflow for all PR operations ('create PR', 'open PR', 'pull request', 'commit and PR'): replaces bash-based gh/git workflows with end-to-end orchestration—handles uncommitted changes (auto-invokes creating-commit/creating-branch), analyzes commit history, generates convention-aware content, detects fork/origin. Canonical PR implementation for git-workflows.

Skill: Creating a Pull Request

When to Use This Skill

Use this skill for pull request creation requests: "create a PR", "open a PR", "submit for review", or similar.

Use other skills for: viewing existing PRs (GitHub MCP directly), updating PRs (GitHub MCP update), or only committing changes (creating-commit).

Workflow Description

Creates GitHub pull requests with automatic commit handling, repository detection, PR content generation, branch pushing, and GitHub PR creation via MCP.

Extract from user request: draft status ("draft"/"WIP" → true, default false), PR title/description (if provided), target branch (if specified, else mainline)


Phase 1: Gather Context (Optimized)

Objective: Collect all PR context and validate prerequisites in a single atomic operation.

Steps:

  1. Determine base branch from user request (optional):

    • Analyze user request for target branch specification
    • Look for phrases like: "create PR to ", "base on ", "merge into ", "target "
    • Common branch names: develop, staging, main, master, release, etc.
    • Store base_branch if found, otherwise let script detect mainline
  2. Run ../../scripts/gather-pr-context.sh (optionally pass base_branch parameter if determined in step 1)

  3. Parse the JSON response and handle results:

IF success: false:

Handle error based on error_type:

  • not_git_repo:

    • STOP: "Not in a git repository"
    • Display: message and suggested_action from response
    • EXIT workflow
  • on_base_branch:

    • STOP: "Cannot create PR from base branch with no new commits"
    • Display: message from response
    • EXPLAIN: "This should rarely occur - if you had uncommitted changes, creating-commit would have been invoked first and handled branch creation"
    • PROPOSE: "Create a feature branch manually or make changes first"
    • EXIT workflow
  • no_commits:

    • STOP: "Branch has no commits to include in PR"
    • Display: message and suggested_action from response
    • EXIT workflow
  • Other errors:

    • STOP: Display error details
    • EXIT workflow

IF success: true:

Extract and store context:

{
  "current_branch": "feature-branch",
  "base_branch": "main",
  "is_fork": true,
  "repository": {
    "upstream_owner": "owner",
    "upstream_repo": "repo",
    "origin_owner": "user",
    "origin_repo": "repo"
  },
  "branch_validation": {
    "is_feature_branch": true,
    "has_uncommitted_changes": false
  },
  "uncommitted_files": [],
  "commit_history": [...],
  "diff_summary": {...},
  "uses_conventional_commits": true
}

Validation Gate: Uncommitted Changes

IF branch_validation.has_uncommitted_changes: true: List files from uncommitted_files array INFORM: "Uncommitted changes detected - creating commit first" INVOKE: creating-commit skill (handles mainline detection internally) WAIT for creating-commit to complete

IF creating-commit succeeded: RE-RUN Phase 1 (gather context again after commit) Continue to Phase 2

IF creating-commit failed: STOP immediately EXPLAIN: "Cannot create PR without committing changes" EXIT workflow

IF no uncommitted changes: Continue to Phase 2

Phase 1 complete. Continue to Phase 2.


Phase 2: Verify PR Base Branch

Objective: Confirm target branch for pull request.

Steps:

  1. Use base_branch from Phase 1 context (already detected mainline)

  2. IF user specified different target branch in Step 1 of Phase 1:

    • Override with user-specified branch
    • INFORM: "Using as PR base (overriding default )"
  3. Store pr_base for later phases

Phase 2 complete. Continue to Phase 3.


Phase 3: Generate PR Content

Objective: Create compelling PR title and description using context from Phase 1.

Generate PR content considering:

  • Commit history and diff summary from Phase 1 context
  • commit_history array (contains hash, subject, body for each commit)
  • diff_summary object (files_changed, insertions, deletions)
  • uses_conventional_commits flag for title format
  • Purpose, scope, key changes, breaking changes
  • Title (<72 chars, imperative) and description
  • Quality and completeness

Steps:

  1. Check user request for explicit title/description; use if provided
  2. If not provided:
    • Title: Use Conventional Commits format if uses_conventional_commits: true from context
    • Description: Generate with sections (Summary, Changes, Motivation, Testing, Additional Notes)
  3. Populate from commit_history and diff_summary in context

Context Available for PR content generation:

  • commit_history: Array of commits with hash, subject, body
  • diff_summary: Files changed, insertions, deletions
  • uses_conventional_commits: Whether to use conventional format for title
  • base_branch: Target branch for PR
  • current_branch: Source branch for PR

Continue to Phase 4.


Phase 4: PR Content Review

Objective: Present generated PR content for user review and approval.

Steps:

  1. Present: Generated PR title and description from Phase 3
  2. Request approval using AskUserQuestion tool:
    • Question: "How would you like to proceed with this pull request?"
    • Header: "PR Content"
    • Options:
      • Proceed: "Create PR with this title and description" - Continues to Phase 5
      • Edit title: "Modify the PR title" - Allows title customization
      • Edit description: "Modify the PR description" - Allows description customization
      • Edit both: "Modify both title and description" - Allows full customization

Validation Gate: Content Approval

HANDLE user selection:

  • IF "Proceed": Continue to Phase 5
  • IF "Edit title":
    • User provides custom title via "Other" option
    • Validate: Title ≤ 72 chars, non-empty
    • IF invalid: Re-prompt with validation message
    • Update title, return to Step 1 to show updated PR
  • IF "Edit description":
    • User provides custom description via "Other" option
    • Validate: Non-empty, markdown formatted
    • Update description, return to Step 1 to show updated PR
  • IF "Edit both":
    • User provides custom title and description via "Other" option
    • Format expected: "TITLE: \n\nDESCRIPTION:\n<description>"</li> <li>Validate both components</li> <li>Update both, return to Step 1 to show updated PR</li> </ul> </li> </ul> <p>Continue to Phase 5.</p> <hr> <h2>Phase 5: Push to Remote</h2> <p><strong>Objective</strong>: Push current branch to remote.</p> <p><strong>Plan Mode</strong>: Auto-enforced read-only if active</p> <p><strong>Steps</strong>:</p> <ol> <li><p>Use <code>current_branch</code> from Phase 1 context (no need to query git)</p> </li> <li><p>Push branch with upstream tracking:</p> <pre><code class="language-bash">git push -u origin <current_branch> </code></pre> </li> </ol> <h3>Validation Gate: Push Failure</h3> <p>IF push fails:</p> <ul> <li>Analyze error:<ul> <li>"fatal: could not read Username": Authentication required</li> <li>"error: failed to push": Rejected, may need force</li> <li>"error: src refspec": Branch doesn't exist</li> <li>Network errors: Connection issues</li> </ul> </li> <li>Explain error clearly</li> <li>Propose solution:<ul> <li>Auth: "Set GITHUB_TOKEN or configure git credentials"</li> <li>Rejected: "Check branch protection rules, may need PR approval"</li> <li>Network: "Check internet connection and retry"</li> </ul> </li> <li>Wait for user to resolve</li> </ul> <p>Continue to Phase 6.</p> <hr> <h2>Phase 6: Create Pull Request</h2> <p><strong>Objective</strong>: Create PR on GitHub using MCP.</p> <p><strong>Plan Mode</strong>: Auto-enforced read-only if active</p> <p><strong>Steps</strong>:</p> <ol> <li><p>Prepare parameters from Phase 1 context:</p> <ul> <li>owner, repo: From <code>repository</code> object</li> <li>head: <code>current_branch</code></li> <li>base: <code>pr_base</code> (from Phase 2)</li> <li>title/body: Generated in Phase 3, approved in Phase 4</li> </ul> </li> <li><p>Determine draft: Check user request for "draft", "WIP", "work in progress"</p> </li> <li><p>Create: <code>mcp__github__create_pull_request</code> with all parameters</p> </li> </ol> <p><strong>Error Handling</strong>: IF failure:</p> <ul> <li>Analyze error to determine cause: auth, permissions, invalid params, duplicate PR, rate limit, or network</li> <li>Explain clearly to user</li> <li>Propose solution and wait for retry approval</li> </ul> <p>Continue to Phase 7.</p> <hr> <h2>Phase 7: Return PR URL</h2> <p><strong>Objective</strong>: Provide PR URL and confirm success with standardized output.</p> <p><strong>Steps</strong>:</p> <ol> <li><p>Extract from Phase 6: PR number, URL, state, title</p> </li> <li><p>Format output using standardized template:</p> <pre><code class="language-markdown">✓ Pull Request Created Successfully **PR Number:** #<number> \ **Title:** <title> \ **URL:** <pr_url> \ **Status:** <Open|Draft> \ **Base Branch:** <base_branch> \ **Head Branch:** <head_branch> [If draft: **Notes:** Mark as 'Ready for review' when ready] [If open: **Notes:** The pull request is ready for review] </code></pre> </li> </ol> <p>Workflow complete.</p> </div> </article> </section> </div> </main> <vercel-analytics data-props="{}" data-params="{"slug":"@majiayu000/claude-skill-registry/creating-pull-request"}" data-pathname="/skills/@majiayu000/claude-skill-registry/creating-pull-request"></vercel-analytics> <script type="module">var f="@vercel/analytics",l="1.5.0",w=()=>{window.va||(window.va=function(...r){(window.vaq=window.vaq||[]).push(r)})};function d(){return typeof window<"u"}function u(){try{const e="production"}catch{}return"production"}function v(e="auto"){if(e==="auto"){window.vam=u();return}window.vam=e}function m(){return(d()?window.vam:u())||"production"}function c(){return m()==="development"}function b(e,r){if(!e||!r)return e;let n=e;try{const t=Object.entries(r);for(const[a,i]of t)if(!Array.isArray(i)){const o=s(i);o.test(n)&&(n=n.replace(o,`/[${a}]`))}for(const[a,i]of t)if(Array.isArray(i)){const o=s(i.join("/"));o.test(n)&&(n=n.replace(o,`/[...${a}]`))}return n}catch{return e}}function s(e){return new RegExp(`/${h(e)}(?=[/?#]|$)`)}function h(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function y(e){return e.scriptSrc?e.scriptSrc:c()?"https://va.vercel-scripts.com/v1/script.debug.js":e.basePath?`${e.basePath}/insights/script.js`:"/_vercel/insights/script.js"}function g(e={debug:!0}){var r;if(!d())return;v(e.mode),w(),e.beforeSend&&((r=window.va)==null||r.call(window,"beforeSend",e.beforeSend));const n=y(e);if(document.head.querySelector(`script[src*="${n}"]`))return;const t=document.createElement("script");t.src=n,t.defer=!0,t.dataset.sdkn=f+(e.framework?`/${e.framework}`:""),t.dataset.sdkv=l,e.disableAutoTrack&&(t.dataset.disableAutoTrack="1"),e.endpoint?t.dataset.endpoint=e.endpoint:e.basePath&&(t.dataset.endpoint=`${e.basePath}/insights`),e.dsn&&(t.dataset.dsn=e.dsn),t.onerror=()=>{const a=c()?"Please check if any ad blockers are enabled and try again.":"Be sure to enable Web Analytics for your project and deploy again. See https://vercel.com/docs/analytics/quickstart for more information.";console.log(`[Vercel Web Analytics] Failed to load script from ${n}. ${a}`)},c()&&e.debug===!1&&(t.dataset.debug="false"),document.head.appendChild(t)}function p({route:e,path:r}){var n;(n=window.va)==null||n.call(window,"pageview",{route:e,path:r})}function k(){try{return}catch{}}customElements.define("vercel-analytics",class extends HTMLElement{constructor(){super();try{const r=JSON.parse(this.dataset.props??"{}"),n=JSON.parse(this.dataset.params??"{}");g({...r,disableAutoTrack:!0,framework:"astro",basePath:k(),beforeSend:window.webAnalyticsBeforeSend});const t=this.dataset.pathname;p({route:b(t??"",n),path:t})}catch(r){throw new Error(`Failed to parse WebAnalytics properties: ${r}`)}}});</script> </body></html>