skills/create-pr/SKILL.md
Skill for pushing branch and creating pull requests with proper target branch detection and draft support. Use when user asks to "create PR", "push and create PR", "open a pull request", or says "/create-pr". Also invoked by /resolve workflow finalization phase. Do NOT use for reviewing PRs (use review-pr skill instead).
npx skillsauth add nicolas-codemate/claudecodeconfig create-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.
This skill handles the finalization phase of ticket resolution: pushing the branch and creating a pull request.
--wait-for-ci) - monitor PR checks, fix failures, retry (bounded)Priority order for determining the PR target branch:
--base main
Read from .claude-work/{ticket-id}/status.json:
{
"options": {
"base_branch": "develop"
}
}
This can be set when creating a worktree, preserving the original base branch.
Some tickets specify target branch:
Check in ticket.md or analysis.md for:
Target Branch: develop
Fix Version: release/2.0
Detect from current branch name:
hotfix/* → main (or master)
release/* → main
feature/* → develop (if exists) or main
fix/* → develop (if exists) or main
From .claude/ticket-config.json:
{
"pr": {
"default_target": "main"
}
}
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@'
Try in order: main, master, develop
Format: {type}: {ticket_title} ({ticket_id})
Examples:
feat: Add CSV export for users (PROJ-123)
fix: Null pointer in login flow (PROJ-456)
refactor: Extract validation service (PROJ-789)
From branch prefix:
feat/ → featfix/ → fixrefactor/ → refactordocs/ → docschore/ → choreBefore generating the body, check if the project has a PR template. Search in order:
.github/pull_request_template.md
.github/PULL_REQUEST_TEMPLATE.md
PULL_REQUEST_TEMPLATE.md
docs/pull_request_template.md
If a template is found:
If no template is found, fall back to the built-in template below.
## Summary
{Brief description from ticket or plan}
## Ticket
- **ID**: {ticket_id}
- **Source**: {YouTrack|GitHub}
- **Link**: {ticket_url}
From config (overrides both project template and built-in):
{
"pr": {
"body_template": "custom template with {{ticket_id}} placeholders",
"include_ticket_link": true
}
}
Check if repository supports draft PRs:
# GitHub - always supports drafts
gh pr create --draft ...
# GitLab - check version
# Bitbucket - check settings
{
"pr": {
"draft_by_default": true
}
}
| Mode | draft_by_default | Result | |------|------------------|--------| | Auto | true | Create as draft | | Auto | false | Create as ready | | Interactive | - | Ask user |
# Check if on feature branch (not main/master)
CURRENT_BRANCH=$(git branch --show-current)
if [[ "$CURRENT_BRANCH" =~ ^(main|master|develop)$ ]]; then
echo "Error: Cannot create PR from protected branch"
exit 1
fi
# Check for uncommitted changes
if [[ -n $(git status --porcelain) ]]; then
echo "Warning: Uncommitted changes detected"
# In interactive: ask to commit or stash
# In auto: fail or stash
fi
# Check if remote exists
git remote get-url origin || exit 1
# Push with upstream tracking
git push -u origin "$CURRENT_BRANCH"
If push fails:
git pull --rebase if behind# Check if PR already exists for this branch
EXISTING_PR=$(gh pr view "$CURRENT_BRANCH" --json number,url 2>/dev/null)
if [[ -n "$EXISTING_PR" ]]; then
PR_URL=$(echo "$EXISTING_PR" | jq -r '.url')
echo "PR already exists: $PR_URL"
# Option: update existing PR description
exit 0
fi
Apply detection priority (see above).
# Verify target branch exists
git ls-remote --heads origin "$TARGET_BRANCH" || {
echo "Error: Target branch '$TARGET_BRANCH' not found"
# Suggest alternatives
}
Search for a PR template in the repository root:
# Check standard locations (first match wins)
for TPL in \
".github/pull_request_template.md" \
".github/PULL_REQUEST_TEMPLATE.md" \
"PULL_REQUEST_TEMPLATE.md" \
"docs/pull_request_template.md"; do
if [[ -f "$TPL" ]]; then
PR_TEMPLATE="$TPL"
break
fi
done
FEATURE_DIR=".claude-work/$TICKET_ID"
TICKET_FILE="$FEATURE_DIR/ticket.md"
PLAN_FILE="$FEATURE_DIR/plan.md"
Extract:
PR_TEMPLATE found: read the template, fill in sections with extracted databody_template set in config: use config template instead (highest priority)# Draft mode
DRAFT_FLAG=""
if [[ "$DRAFT" == "true" ]]; then
DRAFT_FLAG="--draft"
fi
# Create PR
gh pr create \
--title "$PR_TITLE" \
--body "$PR_BODY" \
--base "$TARGET_BRANCH" \
$DRAFT_FLAG
Update .claude-work/{ticket-id}/status.json:
{
"phases": {
"finalize": "completed"
},
"pr": {
"number": 123,
"url": "https://github.com/owner/repo/pull/123",
"draft": true,
"target": "main"
}
}
--wait-for-ci)Skip this step entirely if --wait-for-ci was not passed. Otherwise, parse the optional retry count:
--wait-for-ci → MAX_RETRIES = 3 (default)
--wait-for-ci 5 → MAX_RETRIES = 5
Set a completion goal using the /goal command. This delegates the loop to Claude Code's goal-tracking machinery, with a live overlay showing elapsed time, turns, and tokens. The user can interrupt at any moment with Ctrl+C.
Invoke:
/goal All checks on PR #{PR_NUMBER} are passing (gh pr checks #{PR_NUMBER} reports SUCCESS for every check), OR I have already pushed {MAX_RETRIES} fix attempts for CI failures on this PR.
While /goal is active, repeat:
Poll PR check status
gh pr checks {PR_NUMBER} --json name,state,conclusion
States to handle:
SUCCESS → goal met, stop loop, report successIN_PROGRESS / QUEUED / PENDING → wait, do not act. Re-poll after a short delay (use Bash sleep 30 or wait between turns)FAILURE / STARTUP_FAILURE / TIMED_OUT / CANCELLED AND retry counter < MAX_RETRIES → enter fix mode (step 3)Wait scope: watch ALL checks reported by gh pr checks, including optional ones. Do not filter to required-only.
Fix mode (per failing check): a. Identify the failing run ID:
gh pr checks {PR_NUMBER} --json name,state,conclusion,link,workflow
b. Fetch the failure logs:
gh run view <run_id> --log-failed
If logs are huge, also try gh run view <run_id> --log-failed | tail -200 to focus on the tail.
c. Identify the root cause from the logs. Common categories:
git add -A
git commit -m "fix(ci): {one-line description}"
git push
f. Increment the local retry counter. Mention the counter in your next turn so /goal can track it. g. Wait for the new CI run to start (CI typically picks up the push within 1-2 min), then resume polling.
When /goal exits, produce one of three outcomes in the response:
| Outcome | Trigger | Report |
|---------|---------|--------|
| CI_GREEN | All checks SUCCESS | "PR #{N} CI: tous les checks verts (après {retry_count} fix(es))" |
| CI_RED_EXHAUSTED | Retries exhausted | "PR #{N} CI: {retry_count}/{MAX} tentatives épuisées. Jobs encore en échec: {list}. Investigation manuelle requise." |
| INTERRUPTED | User Ctrl+C | "Watch CI interrompu par l'utilisateur (après {retry_count} fix(es))" |
AskUserQuestion:
question: "Pousser la branche et creer une PR ?"
header: "Finalisation"
options:
- label: "Oui, push + PR"
description: "Pousser la branche et creer la pull request"
- label: "Push seulement"
description: "Pousser sans creer de PR"
- label: "Non, plus tard"
description: "Terminer sans push"
AskUserQuestion:
question: "Creer la PR en mode draft ?"
header: "Draft"
options:
- label: "Oui, draft (Recommended)"
description: "PR en brouillon, a marquer ready apres review"
- label: "Non, ready for review"
description: "PR prete pour review immediate"
AskUserQuestion:
question: "Quelle branche cible pour la PR ?"
header: "Target"
options:
- label: "main (Recommended)"
description: "Branche principale"
- label: "develop"
description: "Branche de developpement"
- label: "{ticket_target}"
description: "Specifie dans le ticket"
--wait-for-ci not already set)AskUserQuestion:
question: "Surveiller la CI et tenter de fixer les echecs automatiquement ?"
header: "Watch CI"
options:
- label: "Non (Recommended)"
description: "Fin du flow apres creation PR. Tu reprends la main sur la CI."
- label: "Oui, max 3 fix-pushes"
description: "Lance /goal: surveille gh pr checks, tente un fix sur echec, push, retry max 3 fois."
- label: "Oui, max 5 fix-pushes"
description: "Pareil avec 5 tentatives. Pour les PRs ou plusieurs checks peuvent casser independamment."
Erreur: Authentification echouee
Solutions:
1. Verifiez vos credentials git
2. Pour HTTPS: gh auth login
3. Pour SSH: ssh-add ~/.ssh/id_rsa
Erreur: Push refuse par protection de branche
La branche '{branch}' a des regles de protection.
Verifiez les settings du repository.
Erreur: Impossible de creer la PR
Verifiez que vous avez les droits sur le repository.
Tentez: gh auth refresh
Erreur: Branche cible '{branch}' introuvable
Branches disponibles:
- main
- develop
- release/2.0
Utilisez --base pour specifier la cible.
Full PR configuration in .claude/ticket-config.json:
{
"pr": {
"draft_by_default": true,
"default_target": "main",
"include_ticket_link": true,
"auto_push": true,
"title_format": "{type}: {title} ({ticket_id})",
"body_template": null,
"wait_for_ci": {
"enabled": false,
"max_retries": 3
}
}
}
| Option | Default | Description |
|--------|---------|-------------|
| draft_by_default | true | Create PRs as draft |
| default_target | "main" | Fallback target branch |
| include_ticket_link | true | Add ticket link in body |
| auto_push | true | Push before creating PR |
| title_format | "{type}: {title} ({ticket_id})" | PR title template |
| body_template | null | Custom body template |
| wait_for_ci.enabled | false | Auto-enable Step 8 (CI watch with fix) without passing --wait-for-ci |
| wait_for_ci.max_retries | 3 | Max fix-push cycles before giving up |
## PR Created
- **Branch**: feat/proj-123-add-csv-export
- **Target**: main
- **PR**: #456
- **URL**: https://github.com/owner/repo/pull/456
- **Status**: Draft
### Next Steps
1. Review the changes
2. Request reviews
3. Mark as ready when done
## PR Already Exists
- **PR**: #456
- **URL**: https://github.com/owner/repo/pull/456
- **Status**: Open
No action needed.
This skill is invoked at the end of the /resolve workflow:
/resolve PROJ-123
│
├─► ... existing phases ...
├─► Implementation
│
└─► Finalize (this skill)
├─► Push branch
├─► Create PR
└─► (optional) Wait for CI with auto-fix
draft_by_default settingpr.wait_for_ci.enabled = true in config, or --wait-for-ci was passed to /resolveUser-facing messages in French. Git commands and PR content in English.
development
Method to diagnose and raise the Lighthouse performance score of a public page (landing, marketing, home). Use when asked to improve Lighthouse/PageSpeed scores, when auditing the first uncached paint of a public page, or when a landing embedded in a SPA must reach a top score. Do NOT use for in-app screen performance (data loading, rendering). For a brand-new landing, the first recommendation is static HTML with no framework runtime — most of this skill exists for when that is not an option.
tools
Audits a project's Claude Code setup against real usage — mines the project's conversations (worktrees included), confronts the project's skills/agents/CLAUDE.md with best practices, and proposes adjustments or new skills/agents/rules. Use when the user asks to audit the project config, analyze project conversations, or find automation opportunities for the current project. Do NOT use for the global ~/.claude configuration (use /audit-config instead).
development
Coaching workflow orchestrator. Guides the developer through implementation without writing code.
development
Disciplined methodology for code architecture refactoring. Use when the user asks to refactor architecture, decouple code, restructure a family of classes, redesign an interface, or rename/reorganize a set of related components. Forces a big-picture analysis before any code is written. Do NOT use for simple bug fixes, feature additions, or single-file refactoring.