| name | pr-description |
| description | Use when generating or updating a PR description for the current branch. Takes an optional issue number as argument. |
| argument-hint | <issue-number> |
/pr-description — Generate or Update PR Description
Generate a structured PR description by analyzing the current branch's changes against the base branch. When an existing PR is found, merges new content with human-added content instead of replacing it.
Input: $ARGUMENTS is an optional GitHub issue number. If provided, include a "Resolves #N" link.
Step 1: Gather Context
Run these commands to understand what changed:
git fetch origin main
git log origin/main...HEAD --oneline
git diff origin/main...HEAD --stat
Read the diff details for any files that need deeper understanding:
git diff origin/main...HEAD
If an issue number was provided, fetch the issue for context:
gh issue view $ARGUMENTS --json title,body,labels
Check for an existing PR on the current branch:
gh pr view HEAD --json number,body,title 2>/dev/null
If this succeeds, an existing PR was found. Save the PR number and body for Step 2.
Best-effort: pull post-merge acceptance criteria from the /implement workpad. When /implement parses a related issue's Acceptance Criteria (its Phase 1.4), it tags items that can only be verified after merge with a trailing (post-merge) marker on the checkbox line. Surface those items in the PR body so the merger sees them and can tick them off after deploy.
If an issue number is available (from $ARGUMENTS or extracted from the existing PR body via (?i)(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+) — mirroring GitHub's own case-insensitive closes-keyword detection), look up the workpad and read its body:
ISSUE_NUMBER=$ARGUMENTS
WORKPAD_ID=$(${CLAUDE_SKILL_DIR}/../../scripts/workpad.py id "$ISSUE_NUMBER" 2>/dev/null || true)
if [ -n "$WORKPAD_ID" ]; then
WORKPAD_BODY=$(${CLAUDE_SKILL_DIR}/../../scripts/workpad.py body "$WORKPAD_ID" 2>/dev/null || true)
fi
If WORKPAD_BODY is set, scan its ## Acceptance Criteria section for lines matching ^[-*]\s+\[[ x]\]\s+.*\(post-merge\)\s*$. Strip the leading checkbox and the trailing (post-merge) tag from each match; collect them as POST_MERGE_ITEMS for Step 2's template.
If no workpad exists, no issue number is available, or no (post-merge)-tagged items are found, POST_MERGE_ITEMS stays empty and the template's Post-Merge Verification section is omitted entirely. The lookup is best-effort — never fail the run on a missing workpad.
Best-effort: pull deferred review findings from the manifest. When /implement Phase 4.0.5 files follow-up issues for /devflow:review-and-fix deferrals, the manifest at .devflow/review/pr-<N>/deferrals.json is updated in place with id and follow_up fields per entry. Surface those entries in the PR body as a Scope-Acknowledged Findings block so /devflow:review (run later as a formal merge signal) can match them and demote the corresponding findings to Informational.
PR_NUMBER=$(gh pr view --json number --jq '.number' 2>/dev/null || true)
if [ -n "$PR_NUMBER" ]; then
DEFERRALS_FILE=".devflow/review/pr-${PR_NUMBER}/deferrals.json"
if [ -s "$DEFERRALS_FILE" ]; then
DEFERRALS_BODY=$(cat "$DEFERRALS_FILE")
fi
fi
If DEFERRALS_BODY is set and the parsed JSON has at least one entry under deferrals[] with a populated follow_up.issue, render the Deferred Findings section in Step 2's template (converting the JSON entries to the YAML shape shown there). Entries lacking a follow_up.issue are stale half-written manifests — skip them silently. Otherwise omit the section entirely. The lookup is best-effort — never fail the run on a missing or unparseable manifest.
Step 2: Generate the PR Description
Mode A: No existing PR (or empty body)
Generate a fresh description using the template below.
Mode B: Existing PR with content
Fetch the existing body and apply these merge rules:
Re-generate from the diff (always overwrite — these reflect current state):
- Summary
- Changes
- Visual Changes
- Breaking Changes
- Post-Merge Verification (when
POST_MERGE_ITEMS is non-empty — re-derived from the workpad on every run so the list stays in sync with the latest /implement parse)
- Deferred Findings (when
DEFERRALS_BODY is non-empty and contains entries with follow_up.issue — re-derived from the manifest on every run so the block stays in sync with the latest /implement Phase 4.0.5 filing)
Merge (keep existing items that are still relevant, add new ones, remove stale ones):
- Test Plan — preserve human-added checklist items; add items for new changes; remove items for changes that no longer exist
Merge (combine existing and new):
- Resolves — if
$ARGUMENTS provides an issue number, include it; also keep any existing issue references that differ from $ARGUMENTS
Preserve as-is:
- Any non-template sections found between the markers (e.g., "## Reviewer Notes", "## Deploy Steps") — carry them forward in the same position
- Any content that appears BEFORE
<!-- PR_BODY_START --> or AFTER <!-- PR_BODY_END --> in the existing body — output it in the same position relative to the markers
If the existing body has NO markers: Treat the entire existing body as pre-marker content. Output it above <!-- PR_BODY_START -->, then generate the full template below the marker.
Template
Output the description as plain text (not inside a code block) so it appears directly in your response:
Summary
- [1-3 concise bullet points describing what changed and why]
Changes
[Group changes by module or concern. Use bold for the area name, colon, then a brief description.]
[Area name]: [What changed]
[Area name]: [What changed]
Resolves
Resolves #[issue number, or omit this section if no issue number was provided]
Test Plan
Post-Merge Verification
[Omit this entire section when POST_MERGE_ITEMS is empty. When non-empty, render as:]
The following items can only be verified after this PR is merged or deployed. Tick each after performing the check.
Deferred Findings
[Omit this entire section when DEFERRALS_BODY is empty or contains no entries with a populated follow_up.issue. When non-empty, render with the markers — the /devflow:review verdict matcher parses them exactly:]
These review-agent findings were deferred under the Scope-Acknowledged Findings contract. /devflow:review honors matching entries as Informational; closing a linked follow-up issue invalidates the deferral and forces re-verification.
schema_version: 1
deferrals:
- id: <dfr-...>
finding:
agent: <agent>
severity: <Critical | Important | Suggestion>
file: <path>
line_range: [<start>, <end>]
symbol: <symbol or empty>
kind: <kind>
summary: |
<verbatim summary>
reason:
category: <out-of-scope | already-tracked | claim-quality>
explanation: |
<verbatim explanation>
follow_up:
issue: <N>
url: <url>
filed_at: <ISO 8601 UTC>
filed_by: <login>
Visual Changes
[Describe UI changes, or "N/A" if none]
Breaking Changes
[Describe breaking changes and migration steps, or "None"]
Rules:
- Be concise. No filler words.
- Summary bullets should explain what and why, not list files.
- Changes section groups by logical area (e.g., "Orders module", "Frontend", "Database"), not individual files.
- Test Plan items must be concrete and actionable, not generic ("Run tests").
- The entire output between the markers must be valid GitHub-flavored Markdown.
- Do NOT wrap the output in a code block. Output the markers and content as plain text so they appear directly in your response.
- When updating an existing PR, do NOT discard human-added content. If in doubt about whether something was human-added, preserve it.
Step 3: Apply the Description