--- description: Generate or update PR description with incremental changes category: version-control-git tools: Bash, Read, Write model: inherit version: 2.0.0 --- # Generate/Update PR Description Generates or updates PR description with incremental information, auto-updates title, and links Linear tickets. ## Prerequisites Before executing, verify all required tools and systems: ```bash # 1. Validate thoughts system (REQUIRED) if [[ -f "scripts/validate-thoughts-setup.sh" ]]; then ./scripts/validate-thoughts-setup.sh || exit 1 else # Inline validation if script not found if [[ ! -d "thoughts/shared" ]]; then echo "❌ ERROR: Thoughts system not configured" echo "Run: ./scripts/humanlayer/init-project.sh . {project-name}" exit 1 fi fi # 2. Validate plugin scripts if [[ -f "${CLAUDE_PLUGIN_ROOT}/scripts/check-prerequisites.sh" ]]; then "${CLAUDE_PLUGIN_ROOT}/scripts/check-prerequisites.sh" || exit 1 fi ``` ## Process: ### 1. Read PR description template ```bash # Check if template exists if [ ! -f "thoughts/shared/pr_description.md" ]; then echo "❌ PR description template not found" fi ``` If missing: ``` ❌ PR description template missing Your humanlayer thoughts setup is incomplete. Create a template at: thoughts/shared/pr_description.md See the PR description template you created earlier for reference. ``` Read template fully to understand all sections. ### 2. Identify target PR **If argument provided:** - Use that PR number: `/describe_pr 123` **If no argument:** ```bash # Try current branch gh pr view --json number,url,title,state,body,headRefName,baseRefName 2>/dev/null ``` If no PR on current branch OR on main/master: ```bash # List recent PRs gh pr list --limit 10 --json number,title,headRefName,state ``` Ask user: "Which PR would you like to describe? (enter number)" ### 3. Extract ticket reference **From multiple sources:** ```bash # 1. From branch name branch=$(gh pr view $pr_number --json headRefName -q .headRefName) if [[ "$branch" =~ ([A-Z]+)-([0-9]+) ]]; then ticket="${BASH_REMATCH[0]}" fi # 2. From PR title title=$(gh pr view $pr_number --json title -q .title) if [[ "$title" =~ ([A-Z]+)-([0-9]+) ]]; then ticket="${BASH_REMATCH[0]}" fi # 3. From existing PR body body=$(gh pr view $pr_number --json body -q .body) if [[ "$body" =~ Refs:\ ([A-Z]+-[0-9]+) ]]; then ticket="${BASH_REMATCH[1]}" fi ``` ### 4. Read existing descriptions **Read current PR body from GitHub:** ```bash current_body=$(gh pr view $pr_number --json body -q .body) ``` **Read saved description (if exists):** ```bash saved_desc="thoughts/shared/prs/${pr_number}_description.md" if [ -f "$saved_desc" ]; then # Read fully # Note what sections exist vs what's new fi ``` **Check for metadata header:** ```markdown ``` ### 5. Gather comprehensive PR information ```bash # Full diff gh pr diff $pr_number # Commit history with messages gh pr view $pr_number --json commits # Changed files gh pr view $pr_number --json files # PR metadata gh pr view $pr_number --json url,title,number,state,baseRefName,headRefName,author # CI/CD status gh pr checks $pr_number ``` ### 6. Analyze changes incrementally **If this is an UPDATE (saved description exists):** ```bash # Extract previous commit list from metadata prev_commits=$(grep "Previous commits:" $saved_desc | sed 's/.*: //') # Get current commits current_commits=$(gh pr view $pr_number --json commits -q '.commits[].oid' | tr '\n' ',' | sed 's/,$//') # Compare new_commits=$(comm -13 <(echo "$prev_commits" | tr ',' '\n' | sort) <(echo "$current_commits" | tr ',' '\n' | sort)) ``` **Analysis:** - Identify what's NEW since last description - Deep analysis of: - Code changes and architectural impact - Breaking changes - User-facing vs internal changes - Migration requirements - Security implications ### 7. Merge descriptions intelligently **Auto-generated sections (always update):** - **Summary** - regenerate based on ALL changes - **Changes Made** - append new changes, preserve old - **How to Verify It** - update checklist, rerun checks - **Changelog Entry** - update to reflect all changes **Preserve manual edits in:** - **Reviewer Notes** - keep existing unless explicitly empty - **Screenshots/Videos** - never overwrite - **Manually checked boxes** - preserve [x] marks for manual steps - **Post-Merge Tasks** - append new, keep existing **Merging strategy:** ```markdown ## Changes Made ### Backend Changes [Existing changes from previous description] **New changes** (since last update): - [New change 1] - [New change 2] ### Frontend Changes [Existing + new merged together] ``` **Add change summary at top:** ```markdown --- **Update History:** - 2025-10-06 15:00: Added validation logic, updated tests (3 new commits) - 2025-10-06 10:30: Initial implementation (5 commits) --- ``` ### 8. Add Linear reference If ticket found: ```markdown ## Related Issues/PRs - Fixes https://linear.app/{workspace}/issue/{ticket} - Related to [any other linked issues] ``` Get Linear ticket details: ```bash # Use Linearis CLI to get ticket details linearis issues read "$ticket" # Extract title and description with jq ticket_title=$(linearis issues read "$ticket" | jq -r '.title') ticket_description=$(linearis issues read "$ticket" | jq -r '.description') ``` Use ticket title and description for context. ### 9. Generate updated title **Title generation rules:** ```bash # If ticket exists if [[ "$ticket" ]]; then # Get ticket title from Linear ticket_title=$(linear API or fallback to branch) # Format: TICKET: Descriptive title (max 72 chars) title="$ticket: ${ticket_title:0:60}" else # Generate from primary change # Analyze commits and code changes title="Brief summary of main change" fi ``` **Auto-update without prompt** - title is auto-generated section. ### 10. Run verification checks **For each checklist item in "How to Verify It":** ```bash # Example: "- [ ] Build passes: `make build`" # Extract command: make build # Try to run if command -v make >/dev/null 2>&1; then if make build 2>&1; then # Mark as checked checkbox="- [x] Build passes: \`make build\` ✅" else # Mark unchecked with error checkbox="- [ ] Build passes: \`make build\` ❌ (failed: $error)" fi else # Can't run checkbox="- [ ] Build passes: \`make build\` (manual verification required)" fi ``` **Common checks to attempt:** - `make test` / `npm test` / `pytest` - `make lint` / `npm run lint` - `npm run typecheck` / `tsc --noEmit` - `make build` / `npm run build` **Document results:** - ✅ if passed - ❌ if failed (with error) - Manual required if can't automate ### 11. Save and sync **Save description:** ```bash # Add metadata header cat > "thoughts/shared/prs/${pr_number}_description.md" < [Full description content] EOF ``` **Sync thoughts:** ```bash humanlayer thoughts sync ``` ### 12. Update PR on GitHub **CRITICAL: NO CLAUDE ATTRIBUTION** Before updating the PR, ensure the description contains NO Claude attribution: ❌ **Remove these if present**: - "Generated with Claude Code" or similar messages - "Co-Authored-By: Claude" lines - Any reference to AI assistance or Anthropic - Links to Claude Code documentation ✅ **Keep descriptions professional and human-authored**: - Focus on code changes and their purpose - Attribute work to the git author (the human developer) - Write in first-person if needed ("I added...", "We implemented...") **Update title:** ```bash gh pr edit $pr_number --title "$new_title" ``` **Update body:** ```bash # Ensure no Claude attribution in the description file gh pr edit $pr_number --body-file "thoughts/shared/prs/${pr_number}_description.md" ``` ### 13. Update Linear ticket If ticket found: ```bash # Verify linearis is available if ! command -v linearis &> /dev/null; then echo "⚠️ Linearis CLI not found - skipping Linear ticket update" else # If not already in "In Review", move it and assign to self linearis issues update "$ticket" --state "In Review" --assignee "@me" # Add comment about update with PR link linearis comments create "$ticket" \ --body "PR description updated!\n\n**Changes**: ${updateSummary}\n**Verification**: ${checksPassedCount}/${totalChecks} automated checks passed\n\nView PR: ${prUrl}" fi ``` ### 14. Report results **If first-time generation:** ``` ✅ PR description generated! **PR**: #123 - {title} **URL**: {url} **Verification**: {X}/{Y} automated checks passed **Linear**: {ticket} updated Manual verification steps remaining: - [ ] Test feature in staging - [ ] Verify UI on mobile Review PR on GitHub! ``` **If incremental update:** ``` ✅ PR description updated! **Changes since last update**: - 3 new commits - Added validation logic - Updated tests **Verification**: {X}/{Y} automated checks passed **Sections updated**: Summary, Changes Made, How to Verify It **Sections preserved**: Reviewer Notes, Screenshots **What changed**: Updated: Summary, Backend Changes, Automated Checks Preserved: Manual verification steps, Reviewer notes Added: New validation section Review updated PR: {url} ``` ## Metadata Management **First generation:** ```markdown ``` **Subsequent updates:** ```markdown --- **Update History:** - 2025-10-06 15:30: Added error handling, fixed tests (2 commits) - 2025-10-06 10:00: Initial implementation (2 commits) --- ``` ## Incremental Update Examples **Example 1: Code review changes** ``` User pushes 2 commits after code review feedback /catalyst-dev:describe_pr detects: - 2 new commits - Changes in validation logic - New tests added Updates: - Appends to "Backend Changes" - Updates "How to Verify It" (reruns test check) - Updates Summary to mention review changes - Preserves reviewer notes and screenshots - Adds to update history ``` **Example 2: Multiple updates** ``` Update 1 (initial): 5 commits Update 2 (review): 3 commits Update 3 (fixes): 2 commits Description shows: - Complete history in update log - All changes accumulated - Latest verification status - All manual notes preserved ``` ## Error Handling **No PR found:** ``` ❌ No PR found for current branch Open PRs: #120 - Feature A (feature-a branch) #121 - Fix B (fix-b branch) Which PR? (enter number) ``` **Template missing:** ``` ❌ PR description template required Create: thoughts/shared/pr_description.md See earlier in conversation for template structure. ``` **Verification command fails:** ``` ⚠️ Some automated checks failed Failed: - make test (exit code 1) Error: 2 tests failed in validation.test.ts Passed: - make lint ✅ - make build ✅ Fix failing tests before merge or document as known issues. ``` ## Configuration Uses `.claude/config.json`: ```json { "catalyst": { "project": { "ticketPrefix": "RCW" }, "linear": { "teamId": "team-id", "inReviewStatusName": "In Review" }, "pr": { "testCommand": "make test", "lintCommand": "make lint", "buildCommand": "make build" } } } ``` ## Remember: - **No interactive prompts** - fully automated - **Incremental updates** - preserve manual edits, append new - **Auto-update title** - based on analysis - **Run verification** - attempt all automated checks - **Link Linear** - extract ticket, update status - **Show what changed** - clear summary of updates - **Full context** - read entire existing description - **Metadata tracking** - commit history, timestamps