agentsclimarketplace

Open pr

Skill mosamaasif/claude-skills/skills/open-pr

Create a GitHub PR with smart defaults, detailed body generation, and user confirmationFrom its SKILL.md

Install
npx -y skills add mosamaasif/claude-skills --skill open-pr

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

17.0 KB, ~4.4k tokens by cl100k_base, as published. Nobody here has run it

/open-pr — GitHub Pull Request Creator

Create a GitHub PR with inferred defaults, a detailed generated body, and mandatory user confirmation before creation. Project-agnostic — works with any repo. Supports PR templates, CODEOWNERS, conventional commits, monorepos, and multiple ticket systems out of the box.

Argument Parsing

Parse arguments from the skill invocation string. All are optional, --flag value format:

ArgAliasDefaultDescription
--base-bInferred (see Phase 2)Target branch
--assignee-aCurrent gh userPR assignee
--reviewer-rAsk userReviewer(s), comma-separated
--label-lInferred from pathsLabel(s), comma-separated
--images-iNoneImage paths for screenshots
--draft-dAsk userCreate as draft
--no-draftCreate as ready for review
--title-tAuto-generatedOverride title
--ticket-jExtracted from branchOverride ticket ID

Execution: 5 Phases

You MUST execute all 5 phases in order. Do NOT skip Phase 4 (confirmation).


Phase 1 — Preflight Checks

Run these checks in parallel where possible:

  1. Auth check: Run gh auth status. If not authenticated, stop and tell the user to run gh auth login.
  2. Uncommitted changes: Run git status --porcelain. If output is non-empty, warn the user about uncommitted changes and ask whether to proceed or abort.
  3. Existing PR: Run gh pr view --json url,state 2>/dev/null. If a PR already exists for this branch:
    • Show the existing PR URL and state
    • Ask user: "A PR already exists. Would you like to update it with gh pr edit instead?"
    • If yes, switch to edit flow (re-generate body, run gh pr edit)
    • If no, abort
  4. Commits ahead: Run git log {base}..HEAD --oneline (after base is determined in Phase 2). If empty, stop — nothing to open a PR for.

Optional Config File

Check for configuration files (strictly optional — skill works perfectly without them):

  1. Check .github/open-pr.yml (repo-level config)
  2. Check ~/.config/open-pr.yml (user-level config)
  3. Repo config overrides user config. CLI flags override both.

Supported config keys:

base: develop                    # default base branch
draft: true                      # default draft status
labels:
  path_mappings:                 # custom path→label mappings
    "packages/payments/": "payments"
    "libs/auth/": "auth"
reviewers:
  default: ["alice"]             # default reviewer suggestions
  use_codeowners: true           # enable CODEOWNERS parsing (default: true)
template: ".github/PULL_REQUEST_TEMPLATE/feature.md"  # force a specific template
body_footer: "QA: https://staging.example.com"        # append to PR body

If config files are not found, proceed silently with built-in defaults. Never error on missing config.

CI Status Warning

After confirming the branch has been pushed (or will be pushed), run:

gh run list --branch {branch} --limit 3 --json status,conclusion,name 2>/dev/null

If any recent runs have conclusion: "failure", warn: "Recent CI runs have failures: {names}. This won't block PR creation, but you may want to investigate." This is advisory only — never block on CI status.


Phase 2 — Gather & Infer Parameters

Ticket ID

  • If --ticket provided, use it directly.
  • Otherwise extract from branch name using priority-ordered patterns:
    1. Jira/Linear: ([A-Z][A-Z0-9]+-\d+) — e.g., DP-1067, ENG-42
    2. Shortcut: (sc-\d+) (case-insensitive) — e.g., sc-12345
    3. Azure DevOps: (AB#\d+) — e.g., AB#7890
    4. GitHub issue: #(\d+) in branch name, or bare number prefix like 123-fix-bug#123
    5. HOTFIX: (HOTFIX) (case-insensitive)
  • Stop at the first match. If no match, ticket ID is empty — that's fine.

Also scan commit messages for issue references (#\d+) to collect related issues for the body.

Base Branch

  • If --base provided, use it.
  • If config file specifies base, use that (unless --base was given).
  • Otherwise detect:
    1. Get the repo default branch: gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
    2. Check common candidates: main, master, develop, plus any release/* branches
    3. For each candidate that exists, compute git merge-base distance
    4. Pick the closest ancestor (fewest commits between merge-base and HEAD)
    5. Fallback: repo default branch
  • Verify the base branch exists on the remote. If not, warn and fall back to the repo default branch.

Stacked PR detection: If the resolved base branch is not main, master, develop, or release/*, note: "This appears to be a stacked PR targeting {base}." Include this note in the Phase 4 preview.

Assignee

  • If --assignee provided, use it.
  • Otherwise: gh api user --jq '.login'

Reviewer

  • If --reviewer provided, use it.
  • Otherwise use a layered strategy, combining results from all available sources:
  1. CODEOWNERS (top priority): Check for .github/CODEOWNERS, CODEOWNERS, or docs/CODEOWNERS. If found, parse it and match changed file paths against patterns. Extract usernames/teams. CODEOWNERS format: each line is pattern @owner1 @owner2. Match using glob patterns (last matching pattern wins per file, same as GitHub). If config has reviewers.use_codeowners: false, skip this step.
  2. Recent file authors: For the top 5 most-changed files (by diff stat), run git log --format='%aN' -5 -- {file}, deduplicate, exclude self.
  3. Recent PR reviewers (fallback): gh pr list --limit 15 --state merged --json author,reviews --jq '.[].reviews[].author.login', deduplicate, exclude self.
  • Combine all results. Label each suggestion with its source:
    • "alice (CODEOWNERS for server/)"
    • "bob (recent author of auth.ts)"
    • "carol (recent PR reviewer)"
  • If config specifies reviewers.default, include those with label "(default from config)".
  • Deduplicate across sources (keep the highest-priority label).
  • Present the combined list to the user via AskUserQuestion (up to 6 options + "Other" + "Skip"). Let them pick one or more.

Labels

  • If --label provided, use those directly.

  • Otherwise:

    1. Fetch available labels: gh label list --json name --jq '.[].name'
    2. If no labels exist in the repo, skip label inference entirely.
    3. Get changed file paths: git diff --name-only {base}..HEAD
    4. Infer labels using a dynamic matching strategy:

    Config-based mappings (if config has labels.path_mappings):

    • Match changed paths against configured path prefixes. Use the mapped label name if it exists in the repo.

    Dynamic directory-to-label matching:

    • Extract directory names from changed file paths (e.g., packages/payments/src/foo.tspackages, payments, src)
    • For each repo label, check if its name (case-insensitive) is a substring of any directory name in the changed paths, or vice versa
    • E.g., label payments matches paths under packages/payments/; label auth matches paths under libs/auth/

    Universal fallback heuristics (always applied):

    • *.md files or paths under docs/ → labels containing "doc"
    • Paths under test/, tests/, __tests__/, or files matching *test*, *spec* → labels containing "test"
    • Paths under .github/, .circleci/, ci/, .gitlab-ci*, Jenkinsfile, Dockerfile, docker-compose*, terraform/, infra/ → labels containing "ci", "infra", or "devops"

    Size labels: Calculate total lines changed from git diff --stat. If the repo has labels matching size/XS, size/S, size/M, size/L, size/XL (case-insensitive):

    • XS: <10 lines, S: <50, M: <200, L: <500, XL: 500+
    • Auto-suggest the matching size label.

    Monorepo package matching: If monorepo detected (see Phase 3), match package/workspace names against available labels.

    1. Present inferred labels to user for confirmation. Let them add/remove before proceeding.
    2. If no labels match, proceed without labels.

Draft Status

  • If --draft provided → draft = true
  • If --no-draft provided → draft = false
  • If config specifies draft, use that as default.
  • Otherwise: ask the user via AskUserQuestion: "Create as draft?" with options "Yes (draft)" and "No (ready for review)"

Phase 3 — Analyze Changes & Generate PR Content

Collect Change Data (run in parallel)

  • git log {base}..HEAD --pretty=format:'%h %s' — commit list
  • git diff --stat {base}..HEAD — file change stats
  • git diff {base}..HEAD — full diff (only if <5000 lines; check with git diff {base}..HEAD | wc -l first)
  • If diff is >5000 lines, warn the user and rely on commit messages + stats only.
  • Count changed files: if >50, warn about large PR.

Size Classification

Calculate total lines changed (additions + deletions from git diff --stat). Classify:

  • XS: <10 lines
  • S: <50 lines
  • M: <200 lines
  • L: <500 lines
  • XL: 500+ lines

Include this in the Phase 4 preview. If XL, add advisory: "This is a very large PR. Consider splitting into smaller, focused PRs for easier review."

Detect Monorepo Structure

Check for monorepo indicators (in parallel with diff collection):

  • pnpm-workspace.yaml, lerna.json, nx.json, rush.json, turbo.json
  • Presence of packages/ or apps/ directories at repo root

If detected, identify which packages/workspaces have changes by mapping changed file paths to package directories. This information is used for:

  • Grouping changes in the PR body by package
  • Package-based label matching (Phase 2)
  • Noting in the summary if changes are scoped to a single package

Detect Conventional Commits

Parse the commit list. Check if >50% of commits follow the pattern type(scope): description or type: description (where type is one of: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert).

If conventional commits are detected:

  • Use the predominant type to inform the title prefix (e.g., feat: → feature PR, fix: → bugfix PR)
  • Group changes by type in the body (Features, Bug Fixes, Refactoring, etc.)
  • If any commit contains BREAKING CHANGE: in its body/footer or uses ! after the type (e.g., feat!:), add a "Breaking Changes" section to the body
  • Still include the ticket ID prefix if present: [TICKET-ID] feat: description

If conventional commits are NOT detected (<=50% match), fall back to the current diff analysis behavior.

Detect PR Template

Before generating the body, check for repository PR templates in this order:

  1. .github/PULL_REQUEST_TEMPLATE.md
  2. .github/pull_request_template.md
  3. PULL_REQUEST_TEMPLATE.md (repo root)
  4. pull_request_template.md (repo root)
  5. Multiple templates in .github/PULL_REQUEST_TEMPLATE/*.md — if found, list them and ask the user to pick one via AskUserQuestion

If config specifies template, use that path directly instead of searching.

If a template is found:

  • Read the template file
  • Preserve its structure: headings, checkboxes, sections, formatting
  • Remove HTML comments (<!-- ... -->) and replace them with actual content generated from the diff/commits
  • Fill in each section intelligently:
    • Summary/description sections → summarize from diff analysis
    • Changes/what sections → list actual changes
    • Testing sections → infer test steps from changes
    • Checklist items → check off items that are clearly satisfied by the diff (e.g., "Tests added" if test files are in the diff)
    • Leave unknown/inapplicable sections with a brief note or empty
  • Append the *Generated with Claude Code* footer

If no template is found, use the built-in template below.

Generate Title

  • If --title provided, use it.
  • Otherwise:
    • Analyze the commits and diff to determine the primary change.
    • If conventional commits detected: use the predominant type as part of the title format.
    • Format: [TICKET-ID] Imperative description if ticket exists, or just Imperative description.
    • For HOTFIX branches: [HOTFIX] Imperative description.
    • Keep under 70 characters.

Generate PR Body (built-in template — used only when no repo template is found)

## Summary
{2-5 bullets: what changed and why, written from analyzing the actual diff and commits}

## Changes
{If monorepo: group by package with package name as sub-heading}
{If conventional commits: group by type — Features, Bug Fixes, Refactoring, etc.}
{Otherwise: group by area}
### {Area/Package/Type 1}
- {specific change}
### {Area/Package/Type 2}
- {specific change}
(use a flat bullet list instead of grouped headings if changes are simple/few)

{If breaking changes detected:}
## Breaking Changes
- {description of breaking change and migration path}

## Related Issues
{List any GitHub issue references found in commits or branch name}
{Use "Closes #123" for issues this PR fixes}
{Use "Relates to #123" for referenced but not fixed issues}
(OMIT this section if no issue references found)

## Screenshots
{embedded images if URLs were provided}
{TODO: drag-and-drop images in browser — if local file paths were provided}
(OMIT this entire section if no images)

## Testing
- [ ] {test item inferred from the changes}
- [ ] {build/compile verification relevant to the project}
- [ ] {manual verification step if applicable}

---
*Generated with [Claude Code](https://claude.com/claude-code)*

If config specifies body_footer, append it before the "Generated with Claude Code" line.

Fill in each section by actually reading and understanding the diff/commits — do not use generic placeholders. The summary and changes sections should reflect what actually changed.


Phase 4 — Confirm with User (MANDATORY — never skip)

Present a full preview to the user. Format it clearly:

=== PR Preview ===

Title:    [DP-1067] Add safe area support
Base:     main
Assignee: mosamaasif
Reviewer: alice (CODEOWNERS), bob (recent author)
Labels:   client, mobile, size/M
Draft:    Yes
Size:     M (142 lines changed)
Template: .github/PULL_REQUEST_TEMPLATE.md
{If stacked PR: "Note: Stacked PR targeting `feature/base-branch`"}
{If monorepo: "Packages: @app/payments, @app/auth"}

--- Body ---
(full PR body from Phase 3)
--- End Body ---

Then ask via AskUserQuestion:

  • "Create this PR?" with options:
    • "Yes, create it"
    • "Edit details" (loop back — ask what to change)
    • "Abort"

If user picks "Edit details", ask what they want to change, apply the change, and show the preview again. Loop until they approve or abort.


Phase 5 — Create PR

  1. Push branch if not already pushed:

    • Check: git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null
    • If no upstream: git push -u origin HEAD
    • If upstream exists but local is ahead: git push
  2. Create the PR using gh pr create:

    gh pr create \
      --base "{base}" \
      --title "{title}" \
      --assignee "{assignee}" \
      --reviewer "{reviewer1},{reviewer2}" \
      --label "{label1},{label2}" \
      {--draft if draft} \
      --body "$(cat <<'PRBODYEOF'
    {generated body}
    PRBODYEOF
    )"
    
    • Omit --reviewer if none selected
    • Omit --label if none selected
    • Omit --draft if not draft
  3. Display the result:

    • Show the PR URL returned by gh pr create
    • If local image files were provided via --images, remind: "Local images can't be uploaded via CLI. Open the PR in your browser and drag-and-drop the images into the Screenshots section."
    • Post-creation hint: "Monitor CI checks with gh pr checks."

Edge Case Handling

  • No ticket ID in branch: Omit [TASK-ID] prefix from title and omit ticket-related content from body.
  • HOTFIX branches: Use [HOTFIX] prefix. No ticket link.
  • PR already exists: Detected in Phase 1. Offer gh pr edit flow.
  • Very large diffs (>5000 lines or 50+ files): Warn user. Rely on commit messages and --stat for body generation.
  • Local image files: Remind user to manually upload after PR creation.
  • Base branch missing on remote: Fall back to repo default branch with a warning.
  • No labels in repo: Skip label inference silently.
  • No reviewers found: Skip reviewer suggestion, allow manual entry.
  • gh CLI not installed: Stop immediately with install instructions.
  • Not a git repo: Stop immediately.
  • No PR template found: Use built-in template — never error on missing template.
  • No CODEOWNERS file: Skip CODEOWNERS step, fall through to other reviewer strategies.
  • No conventional commits: Fall back to diff-based analysis for title and body grouping.
  • Not a monorepo: Use flat file grouping — no package-level grouping.
  • No config file: Proceed with built-in defaults — config is strictly optional.
  • Config file has unknown keys: Ignore unknown keys silently.
  • Multiple PR templates directory: Ask user to pick one.
  • Stacked PR (non-standard base): Show advisory note, don't change behavior.
  • CI failures on branch: Show warning, don't block PR creation.

What ships with it: 1 file

3.3 KB alongside SKILL.md

Keep looking

Skills are one crate of 326,512. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.