--- description: Create pull request with automatic Linear integration category: version-control-git tools: Bash(linearis *), Bash(git *), Bash(gh *), Read, Task model: inherit version: 1.0.0 --- # Create Pull Request Orchestrates the complete PR creation flow: commit → rebase → push → create → describe → link Linear ticket. ## Prerequisites Before executing, verify required tools are installed: ```bash if [[ -f "${CLAUDE_PLUGIN_ROOT}/scripts/check-prerequisites.sh" ]]; then "${CLAUDE_PLUGIN_ROOT}/scripts/check-prerequisites.sh" || exit 1 fi ``` ## Configuration Read team configuration from `.claude/config.json`: ```bash CONFIG_FILE=".claude/config.json" TEAM_KEY=$(jq -r '.catalyst.linear.teamKey // "PROJ"' "$CONFIG_FILE") ``` ## Process: ### 1. Check for uncommitted changes ```bash git status --porcelain ``` If there are uncommitted changes: - Offer to commit: "You have uncommitted changes. Create commits now? [Y/n]" - If yes: internally call `/catalyst-dev:commit` workflow - If no: proceed (user may want to commit manually later) ### 2. Verify not on main/master branch ```bash branch=$(git branch --show-current) ``` If on `main` or `master`: - Error: "Cannot create PR from main branch. Create a feature branch first." - Exit ### 3. Detect base branch ```bash # Check which exists if git show-ref --verify --quiet refs/heads/main; then base="main" elif git show-ref --verify --quiet refs/heads/master; then base="master" else base=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@') fi ``` ### 4. Check if branch is up-to-date with base ```bash # Fetch latest git fetch origin $base # Check if behind if git log HEAD..origin/$base --oneline | grep -q .; then echo "Branch is behind $base" fi ``` If behind: - Auto-rebase: `git rebase origin/$base` - If conflicts: - Show conflicting files - Error: "Rebase conflicts detected. Resolve conflicts and run /catalyst-dev:create_pr again." - Exit ### 5. Check for existing PR ```bash gh pr view --json number,url,title,state 2>/dev/null ``` If PR exists: - Show: "PR #{number} already exists: {title}\n{url}" - Ask: "What would you like to do?\n [D] Describe/update this PR\n [S] Skip (do nothing)\n [A] Abort" - If D: call `/catalyst-dev:describe_pr` and exit - If S: exit with success message - If A: exit - **This is the ONLY interactive prompt in the happy path** ### 6. Extract ticket from branch name ```bash branch=$(git branch --show-current) # Extract pattern: PREFIX-NUMBER using configured team key if [[ "$branch" =~ ($TEAM_KEY-[0-9]+) ]]; then ticket="${BASH_REMATCH[1]}" # e.g., RCW-13 fi ``` ### 7. Generate PR title from branch and ticket ```bash # Branch format examples: # - RCW-13-implement-pr-lifecycle → "RCW-13: implement pr lifecycle" # - feature-add-validation → "add validation" # Extract description from branch name if [[ "$ticket" ]]; then # Remove ticket prefix from branch desc=$(echo "$branch" | sed "s/^$ticket-//") # Convert kebab-case to spaces desc=$(echo "$desc" | tr '-' ' ') # Capitalize first word desc="$(tr '[:lower:]' '[:upper:]' <<< ${desc:0:1})${desc:1}" title="$ticket: $desc" else # No ticket in branch desc=$(echo "$branch" | tr '-' ' ') desc="$(tr '[:lower:]' '[:upper:]' <<< ${desc:0:1})${desc:1}" title="$desc" fi ``` ### 8. Push branch ```bash # Check if branch has upstream if ! git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null; then # No upstream, push with -u git push -u origin HEAD else # Has upstream, check if up-to-date git push fi ``` ### 9. Create PR **CRITICAL: NO CLAUDE ATTRIBUTION** DO NOT add any of the following to the PR: - ❌ "Generated with Claude Code" or similar messages - ❌ "Co-Authored-By: Claude" lines - ❌ Any reference to AI assistance - ❌ Links to Claude Code or Anthropic The PR should be authored solely by the user (git author). Keep the description clean and professional. ```bash # Minimal initial body (NO CLAUDE ATTRIBUTION) body="Automated PR creation. Comprehensive description generating..." # If ticket exists, add reference if [[ "$ticket" ]]; then body="$body\n\nRefs: $ticket" fi # Create PR (author will be the git user) gh pr create --title "$title" --body "$body" --base "$base" ``` Capture PR number and URL from output. ### Track in Workflow Context After creating the PR, add it to workflow context: ```bash if [[ -f "${CLAUDE_PLUGIN_ROOT}/scripts/workflow-context.sh" ]]; then "${CLAUDE_PLUGIN_ROOT}/scripts/workflow-context.sh" add prs "$PR_URL" "${TICKET_ID:-null}" fi ``` ### 10. Auto-call /catalyst-dev:describe_pr Immediately call `/catalyst-dev:describe_pr` with the PR number to: - Generate comprehensive description - Run verification checks - Update PR title (refined from code analysis) - Save to thoughts/ - Update Linear ticket ### 11. Update Linear ticket (if ticket found) If ticket was extracted from branch: ```bash # Verify linearis is available if ! command -v linearis &> /dev/null; then echo "⚠️ Linearis CLI not found - skipping Linear ticket update" echo "Install: npm install -g --install-links ryanrozich/linearis#feat/cycles-cli" else # Update ticket state to "In Review" linearis issues update "$ticket" --state "In Review" --assignee "@me" # Add comment with PR link linearis comments create "$ticket" \ --body "PR created and ready for review!\n\n**PR**: $prUrl\n\nDescription has been auto-generated with verification checks." fi ``` ### 12. Report success ``` ✅ Pull request created successfully! **PR**: #{number} - {title} **URL**: {url} **Base**: {base_branch} **Ticket**: {ticket} (moved to "In Review") Description has been generated and verification checks have been run. Review the PR on GitHub! ``` ## Error Handling **On main/master branch:** ``` ❌ Cannot create PR from main branch. Create a feature branch first: git checkout -b TICKET-123-feature-name ``` **Rebase conflicts:** ``` ❌ Rebase conflicts detected Conflicting files: - src/file1.ts - src/file2.ts Resolve conflicts and run: git add git rebase --continue /catalyst-dev:create_pr ``` **GitHub CLI not configured:** ``` ❌ GitHub CLI not configured Run: gh auth login Then: gh repo set-default ``` **Linearis CLI not found:** ``` ⚠️ Linearis CLI not found PR created successfully, but Linear ticket not updated. Install Linearis: npm install -g --install-links ryanrozich/linearis#feat/cycles-cli Configure: export LINEAR_API_TOKEN=your_token ``` **Linear ticket not found:** ``` ⚠️ Could not find Linear ticket for {ticket} PR created successfully, but ticket not updated. Update manually or check ticket ID. ``` ## Configuration Uses `.claude/config.json`: ```json { "catalyst": { "project": { "ticketPrefix": "RCW" }, "linear": { "teamKey": "RCW", "inReviewStatusName": "In Review" } } } ``` ## Examples **Branch: `RCW-13-implement-pr-lifecycle`** ``` Extracting ticket: RCW-13 Generated title: "RCW-13: Implement pr lifecycle" Creating PR... ✅ PR #2 created Calling /catalyst-dev:describe_pr to generate description... Updating Linear ticket RCW-13 → In Review ✅ Complete! ``` **Branch: `feature-add-validation` (no ticket)** ``` No ticket found in branch name Generated title: "Feature add validation" Creating PR... ✅ PR #3 created Calling /catalyst-dev:describe_pr... ⚠️ No Linear ticket to update ✅ Complete! ``` ## Integration with Other Commands - **Calls `/catalyst-dev:commit`** - if uncommitted changes (optional) - **Calls `/catalyst-dev:describe_pr`** - always, to generate comprehensive description - **Sets up for `/catalyst-dev:merge_pr`** - PR is now ready for review and eventual merge ## Remember: - **Minimize prompts** - only ask when PR already exists - **Auto-rebase** - keep branch up-to-date with base - **Auto-link Linear** - extract ticket from branch, update status with Linearis CLI - **Auto-describe** - comprehensive description generated immediately - **Fail fast** - stop on conflicts or errors with clear messages - **Graceful degradation** - If Linearis not installed, warn but continue