AgentSkillsCN

kramme:create-pr

创建清晰的 PR,附带叙事式提交与全面的描述。

SKILL.md
--- frontmatter
name: kramme:create-pr
description: Create a clean PR with narrative commits and comprehensive description
disable-model-invocation: true
user-invocable: true

Create Pull Request

Orchestrate the creation of a clean, well-documented draft PR by:

  1. Validating git state and detecting platform
  2. Setting up the branch (if on main)
  3. Creating clean, narrative-quality commits
  4. Generating a comprehensive description
  5. Pushing and creating the draft PR

Process Overview

code
/create-pr
    |
    v
[Pre-Validation] -> Error? -> Abort with clear message
    |
    v
[Platform Detection] -> Ambiguous? -> Ask user
    |
    v
[Branch Handling] -> On main? -> Linear issue? -> Use Linear branch name / Ask for branch name
    |
    v
[Changes Check] -> No changes? -> Abort
    |
    v
[State Preservation] -> Record original state for rollback
    |
    v
[recreate-commits Skill] -> Failure? -> Rollback
    |
    v
[pr-description-generator Skill]
    |
    v
[Confirmation] -> Abort? -> Rollback
    |
    v
[Push & Create Draft PR]
    |
    v
[Success Output]

Step 1: Pre-Validation

ALWAYS perform these checks before proceeding. Abort on any failure.

1.1 Git Repository Check

bash
git rev-parse --is-inside-work-tree 2>/dev/null

If this fails:

code
Error: Not inside a git repository.

Navigate to a git project directory and run /create-pr again.

Action: Abort immediately.

1.2 Merge Conflict Check

bash
git ls-files -u

If output is non-empty (conflicts exist):

code
Error: Merge conflict detected.

Conflicted files:
  - [list files from output]

Please resolve these conflicts before creating a PR:
  1. Edit the conflicted files to resolve markers (<<<<<<<, =======, >>>>>>>)
  2. Stage resolved files: git add <resolved-files>
  3. Complete the merge: git commit

Then run /create-pr again.

Action: Abort.

1.3 Rebase/Merge In Progress Check

Check for these paths:

  • .git/rebase-merge/
  • .git/rebase-apply/
  • .git/MERGE_HEAD

If any exist:

code
Error: [Rebase/Merge] operation in progress.

To continue: git [rebase/merge] --continue
To abort: git [rebase/merge] --abort

Resolve the in-progress operation, then run /create-pr again.

Action: Abort.

1.4 Remote Configuration Check

bash
git remote get-url origin 2>/dev/null

If no remote configured:

code
Error: No remote 'origin' configured.

Add a remote first:
  git remote add origin <repository-url>

Then run /create-pr again.

Action: Abort.


Step 2: Platform Detection

Parse the remote URL from Step 1.4:

bash
REMOTE_URL=$(git remote get-url origin)

Detection logic:

URL ContainsPlatformCLI Tool
github.comGitHubgh
gitlab.comGitLabglab or MCP
consensusapsGitLabglab or MCP

If platform cannot be determined:

Use AskUserQuestion:

yaml
header: "Platform"
question: "Could not detect platform from remote URL. Which platform are you using?"
options:
  - label: "GitHub"
    description: "Will create a Pull Request using the gh CLI"
  - label: "GitLab"
    description: "Will create a Pull Request using glab CLI or MCP tools"
multiSelect: false

Store the detected platform for later steps.


Step 3: Branch Handling

3.1 Get Current Branch

bash
git branch --show-current

3.2 Determine Main Branch

bash
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||'

If this fails, try main then master.

3.3 Branch Decision

If current branch is main or master:

3.3.1 Check for Linear Issue

First, ask if working on a Linear issue:

yaml
header: "Branch source"
question: "Are you working on a Linear issue?"
options:
  - label: "Yes, I have a Linear issue ID"
    description: "Will use Linear's branch naming convention (e.g., initials/wan-521-description)"
  - label: "No, generate from file changes"
    description: "Will suggest branch names based on changed files"
multiSelect: false

3.3.2 If "Yes, I have a Linear issue ID":

  1. Ask for the issue ID (user enters via "Other" free-text option):

    yaml
    header: "Linear issue"
    question: "Enter the Linear issue ID (e.g., WAN-521):"
    options: []
    
  2. Fetch issue details using Linear MCP:

    code
    mcp__linear__get_issue with id: {issue-id}
    
  3. If fetch fails (MCP unavailable or issue not found):

    code
    Warning: Could not fetch Linear issue {issue-id}.
    
    Error: {error message}
    
    Falling back to file-based branch naming.
    

    Continue with file-based naming (Step 3.3.3).

  4. If fetch succeeds and branchName is available:

    • Use the branchName directly from the Linear response as {branchName}
  5. If fetch succeeds but branchName is empty/missing:

    • Ask for user initials:
      yaml
      header: "Initials"
      question: "Enter your initials for the branch name (e.g., 'jd'):"
      options: []
      
    • Generate branch name: {initials}/{issue-id-lowercase}-{sanitized-title}
    • Sanitize title: lowercase, replace spaces/special chars with hyphens, max 50 chars
    • Use the generated name as {branchName}
  6. Check if branch exists (local or remote):

    bash
    # Check if branch exists locally
    git rev-parse --verify {branchName} 2>/dev/null
    
    # Check if branch exists on remote
    git ls-remote --heads origin {branchName}
    

    If branch exists locally:

    Use AskUserQuestion:

    yaml
    header: "Branch Exists"
    question: "Branch '{branchName}' already exists locally. What should I do?"
    options:
      - label: "Switch to existing branch"
        description: "Continue work on the existing branch"
      - label: "Delete and recreate"
        description: "Start fresh from main/master"
      - label: "Use different name"
        description: "Create branch with '-v2' suffix"
    

    If branch exists only on remote:

    bash
    git checkout -b {branchName} origin/{branchName}
    
  7. If branch doesn't exist:

    bash
    # Determine base branch
    BASE=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||') || BASE="main"
    
    # Fetch latest
    git fetch origin $BASE
    
    # Create branch from latest base
    git checkout -b {branchName} origin/$BASE
    

3.3.3 If "No, generate from file changes" (or fallback):

  1. Analyze changed files to suggest branch names:

    bash
    # Get changed files (staged + unstaged + untracked)
    git diff --name-only HEAD
    git diff --name-only --cached
    git status --porcelain | grep '^??' | cut -c4-
    
  2. Generate suggestions based on file paths:

    • Files in apps/ or libs/ -> extract component name
    • New files -> prefix with feature/
    • Test files only -> prefix with test/
    • Config files -> prefix with chore/
  3. Use AskUserQuestion:

    yaml
    header: "Branch name"
    question: "You're on the main branch. What should the new branch be named?"
    options:
      - label: "feature/{suggested-name-1}"
        description: "Based on changes in {primary-area}"
      - label: "fix/{suggested-name-2}"
        description: "Based on modifications to {component}"
      - label: "chore/{suggested-name-3}"
        description: "Based on config/tooling changes"
    multiSelect: false
    
  4. Create and switch to new branch:

    bash
    git checkout -b {chosen-branch-name}
    

If already on a feature branch: Continue with current branch. No action needed.


Step 4: Changes Detection

4.1 Check for Uncommitted Changes

bash
git status --porcelain

4.2 Check for Commits Ahead of Main

bash
git rev-list --count origin/main..HEAD 2>/dev/null || git rev-list --count origin/master..HEAD

4.3 Validation

If both checks return empty/zero:

code
Error: No changes detected compared to main branch.

Current state:
  - Branch: {current-branch}
  - Uncommitted changes: None
  - Commits ahead of main: 0

Nothing to create a PR for. Make some changes first, then run /create-pr again.

Action: Abort.

If changes exist: Continue to next step.


Step 5: State Preservation

Before any destructive operations, record the current state for potential rollback.

5.1 Record Original State

bash
ORIGINAL_BRANCH=$(git branch --show-current)
ORIGINAL_COMMIT=$(git rev-parse HEAD)

5.2 Stash Uncommitted Changes

If there are uncommitted changes:

bash
git stash push -m "create-pr-backup-$(date +%s)"
STASH_CREATED=true

5.3 Rollback Procedure

If rollback is needed at any point, execute:

bash
# Return to original branch
git checkout $ORIGINAL_BRANCH

# Delete clean branch if created
git branch -D ${ORIGINAL_BRANCH}-clean 2>/dev/null || true

# Restore stashed changes
if [ "$STASH_CREATED" = "true" ]; then
  git stash pop
fi

Step 6: Invoke recreate-commits Skill (Step 6 of 9 - DO NOT STOP AFTER THIS STEP)

6.1 Confirm Commit Restructuring Approach

Use AskUserQuestion:

yaml
header: "Commit style"
question: "How should commits be structured for the PR?"
options:
  - label: "Narrative (recommended)"
    description: "Reorganize into logical story: setup, core implementation, tests, polish"
  - label: "Keep original"
    description: "Keep existing commit structure, just clean up messages"
  - label: "Single squash"
    description: "Combine all changes into one well-documented commit"
multiSelect: false

6.2 Invoke the Skill

IMPORTANT: Use the Skill tool to invoke recreate-commits:

code
skill: "kramme:recreate-commits"

This skill will:

  • Analyze all changes vs main/master
  • Plan a logical commit sequence
  • Create narrative-quality commits
  • NEVER include AI attribution (no "Generated with Claude Code" or Co-Authored-By)

⚠️ MANDATORY CONTINUATION - DO NOT STOP HERE

After the recreate-commits skill completes:

  1. DO NOT end your turn or wait for user input
  2. DO NOT summarize what was done and ask "what next?"
  3. IMMEDIATELY invoke the pr-description-generator skill (Step 7)

This is Step 6 of 9. The PR creation workflow is not complete until Step 9.

6.3 Handle Skill Failure

If the skill fails or encounters an error:

code
Error: The recreate-commits skill encountered an issue.

Original state preserved:
  - Branch: {original-branch}
  - Commit: {original-commit}

What happened:
  {skill error message}

Recovery:
  1. Your original work is safe
  2. Check git status to see current state
  3. If a -clean branch was created: git branch -D {branch}-clean
  4. Try again with /create-pr

Action: Execute rollback procedure from Step 5.3, then abort.


Step 7: Invoke pr-description-generator Skill (Step 7 of 9 - DO NOT STOP AFTER THIS STEP)

7.1 Invoke the Skill

IMPORTANT: Use the Skill tool to invoke pr-description-generator:

code
skill: "kramme:pr-description-generator"

This skill will:

  • Analyze git diff and commit history
  • Check for Linear issue references in branch name
  • Ask clarifying questions about the changes
  • Generate a conventional commit-style title (<type>(<scope>): <description>)
  • Generate comprehensive description with all sections

⚠️ MANDATORY CONTINUATION - DO NOT STOP HERE

After the pr-description-generator skill completes:

  1. DO NOT end your turn or wait for user input
  2. DO NOT just show the description and stop
  3. IMMEDIATELY proceed to Step 8 (Confirmation and Creation)

This is Step 7 of 9. The PR creation workflow is not complete until Step 9. The skill may ask its own clarifying questions; once it produces the final description, proceed directly to the Confirmation and Creation step.

7.2 Capture the Title and Description

The skill produces:

  1. A conventional commit-style title (e.g., feat(auth): add OAuth2 support)
  2. A complete markdown description

Capture both for use in Step 8.

7.3 Handle Skill Failure

If the skill fails:

Provide a minimal fallback template:

markdown
## Summary

[Brief description of changes]

## Technical Details

[Implementation approach]

## Test Plan

- [ ] Manual testing completed
- [ ] Unit tests pass

## Breaking Changes

None

Continue to Step 8 with the fallback template.


Step 8: Confirmation and Creation (Step 8 of 9)

8.1 Preview Summary

Show the user what will be created:

code
Draft [PR] Ready to Create

Platform: [GitHub/GitLab]
Title: [Generated conventional commit title from pr-description-generator]
Branch: {feature-branch} -> main
Status: Draft

Description Preview:
---
{first 300 characters of description}...
---

NOTE: The title comes from the pr-description-generator skill output and follows conventional commit format (<type>(<scope>): <description>).

8.2 Confirm Creation

Use AskUserQuestion:

yaml
header: "Confirm"
question: "Ready to create the Draft PR?"
options:
  - label: "Create Draft PR"
    description: "Push branch and create draft PR with the generated description"
  - label: "Edit description first"
    description: "Review and modify the description before creating"
  - label: "Abort"
    description: "Cancel and keep local changes without creating PR"
multiSelect: false

If "Abort" selected:

code
Operation cancelled.

Your changes remain local:
  - Branch: {current-branch}
  - Commits: {number} commits ready
  - Status: Not pushed, no PR created

You can run /create-pr again when ready.

Action: Abort (no rollback needed - commits are preserved).

If "Edit description first" selected: Allow the user to provide edits, then continue.

8.3 Push Branch

bash
git push -u origin $(git branch --show-current)

If push fails:

code
Warning: Failed to push branch to remote.

Possible causes:
  - No push access to repository
  - Branch name conflicts with existing remote branch
  - Network connectivity issues

Manual push command:
  git push -u origin {branch-name}

If branch exists remotely:
  git push -u origin {branch-name} --force-with-lease

The generated description is saved. You can create the PR manually.

Action: Show the full description for copy/paste, then abort.

8.4 Create Draft PR

For GitHub:

bash
gh pr create --draft \
  --assignee @me \
  --title "{title}" \
  --body "$(cat <<'EOF'
{generated description}
EOF
)"

For GitLab (using glab CLI):

bash
# Determine the logged-in GitLab username
GLAB_USER="$(glab api /user | python3 -c 'import sys, json; print(json.load(sys.stdin)["username"])')"

glab mr create --draft \
  --assignee "$GLAB_USER" \
  --title "{title}" \
  --description "$(cat <<'EOF'
{generated description}
EOF
)"

# Alternative (if jq is installed):
# GLAB_USER="$(glab api /user | jq -r '.username')"

For GitLab (using MCP tools, if available): Use mcp__gitlab__create_merge_request with draft: true (or prefix title with Draft: ) and include assignee_id set to the current user's ID.

8.5 Handle PR Creation Failure

If creation fails:

code
Warning: Failed to create [PR] automatically.

Error: {error message}

Manual creation:
  1. Your branch is pushed: origin/{branch-name}
  2. Create manually at:
     [GitHub]: https://github.com/{org}/{repo}/pull/new/{branch}
     [GitLab]: https://gitlab.com/{org}/{repo}/-/merge_requests/new
  3. Copy this description:

---
{full generated description}
---

Remember to mark it as Draft before creating.

Step 9: Success Output

On successful creation:

code
Draft [PR] created successfully!

URL: {pr-url}
Branch: {branch} -> main
Status: Draft

Commits included:
  - {commit 1 summary}
  - {commit 2 summary}
  - ...

Next steps:
  1. Review the PR description for accuracy
  2. Add screenshots or videos if applicable
  3. Run tests and ensure CI passes
  4. Mark as ready for review when complete

Step 10: Abort and Rollback Handling

If abort is requested at any point, or a critical failure occurs:

10.1 Execute Rollback

bash
# Return to original branch
git checkout $ORIGINAL_BRANCH

# Reset to original commit if needed
git reset --hard $ORIGINAL_COMMIT

# Delete temporary branches
git branch -D ${ORIGINAL_BRANCH}-clean 2>/dev/null || true

# Restore stashed changes
if [ "$STASH_CREATED" = "true" ]; then
  git stash pop
fi

10.2 Confirm Rollback

code
Operation Aborted

Restored state:
  - Branch: {original-branch}
  - Commit: {original-commit}
  - Uncommitted changes: Restored from stash

Cleanup performed:
  - Deleted temporary branches
  - Restored stashed changes

Your work is exactly as it was before running /create-pr.

Important Constraints

No AI Attribution

NEVER add these to commits:

  • Generated with [Claude Code]
  • Co-Authored-By: Claude
  • Any mention of AI assistance

Per the recreate-commits skill requirements, this would cause issues.

Always Draft

ALWAYS create PRs as Draft:

  • GitHub: Use --draft flag
  • GitLab: Use --draft flag or Draft: title prefix

Never create a ready-for-review PR directly.

Preserve Authorship

NEVER modify git config or add AI as author. All commits should reflect the user's authorship.

Complete All Steps

Even for simple changes, invoke both skills:

  1. recreate-commits for clean commit history
  2. pr-description-generator for comprehensive description

This ensures consistency across all PRs.