pull-request · diff
git:20260128.d4d59c8 to git:20260420.12d472c
92 added, 514 removed. Audit A to A.
---
name: pull-request
- description: Use when creating, updating, or commenting on GitHub pull requests - focuses on material impact, safety, and human reviewability
+ description: Invoke this skill BEFORE running any gh pr create, gh pr edit, or gh pr comment command, or any task that will produce or modify a GitHub pull request. This is the skill for authoring outbound PR communication: creating, drafting, opening, filing, or starting a PR; updating a PR body or description; posting a comment or reply to review feedback. Trigger on short and casual phrasings, not only the literal word "create". Example triggers: "create a PR", "draft a PR", "open a PR", "file a PR", "push and PR it", "push up a draft PR", "PR this branch", "PR it", "time to PR this", "let's start a PR", "commit these and push a PR", "update the PR body", "rewrite the PR description", "comment on the PR", "reply to the review comments", "reply to copilot". Do NOT use for reviewing someone else's PR, merging, checking CI/build status, listing review requests, checking out PRs locally, or cleaning up merged branches. Those are separate skills.
---
- # GitHub PR Communication Skill
-
- Use this skill for creating, updating, or commenting on GitHub pull requests. Focus on material impact, safe operations, and respecting busy reviewers.
-
- ## When to Use This Skill
-
- - Creating PRs from feature branches
- - Updating PR descriptions after significant changes
- - Adding comments to communicate with reviewers
- - Any PR communication task
-
- ## Announcement
-
- Always announce at start:
-
- ```
- "I'm using the gh-pr skill to <create|update|comment on> the pull request."
- ```
-
- ## Core Principles
-
- 1. **Safety first:** All PR bodies written to `.scratch/pr-bodies/` before use with `gh --body-file`
- 2. **Material impact:** Focus on why changes matter, not metrics or file counts
- 3. **Smart merge:** Detect manual edits, only update when changes are material
- 4. **Human-friendly:** Concise, warm tone; assume busy reviewer
- 5. **Flexible workflow:** Explicit commands when clear, smart routing when ambiguous
-
- ## File Structure
-
- ```
- .scratch/pr-bodies/
- drafts/
- <slugified-title>.md # Draft body before PR creation
- <pr-number>/
- metadata.json # PR metadata and state
- <timestamp>-body.md # Timestamped snapshots of generated bodies
- <timestamp>-comment.md # Comment drafts
- ```
-
- ### Metadata Schema
-
- ```json
- {
- "pr_number": 123,
- "branch": "feature/add-skill",
- "base": "main",
- "title": "Add spotlight exclusion skill",
- "created_at": "2025-11-07T10:30:00Z",
- "last_generated_hash": "abc123def456",
- "last_updated_at": "2025-11-07T16:45:30Z",
- "manual_edits_detected": false
- }
- ```
-
- ## Trigger Patterns
-
- ### Explicit Triggers (Always Honored)
-
- - **"create a PR"** / **"open a PR"** → Create flow
- - **"update the PR body/description"** → Update body flow
- - **"comment on the PR"** / **"add a PR comment"** → Comment flow
-
- ### Ambiguous Triggers (Smart Routing)
-
- **"update the PR":**
-
- - No PR exists → Error: "No PR found for this branch. Did you mean to create one?"
- - PR exists, no reviews → Update body
- - PR exists, has reviews → Ask: "This PR has reviews. Update body or add comment?"
-
- **"communicate the changes":**
-
- - PR exists, no reviews yet → Update body
- - PR exists, has reviews → Add comment (generates notifications)
-
- ## Operation Flows
-
- ### 1. Create PR
-
- ```
- ☐ Check if PR already exists
- - gh pr view --json number 2>/dev/null
- - If exists → error or route to update
-
- ☐ Gather information
- - Commits: git log <base>..HEAD
- - Check for PR template (.github/pull_request_template.md, etc.)
- - Check for CONTRIBUTING.md
- - Analyze commit messages and diffs
-
- ☐ Generate PR content
- - Title: from branch name or first commit (imperative mood, <72 chars)
- - Body:
- * Follow template structure if exists
- * Summary: 2-4 bullets of material impact
- * Test plan: if non-obvious
- * NO H1 heading (GitHub shows title separately)
- * NO metrics (# tests, # files, etc.)
- * Concise, warm tone
-
- ☐ Draft review
- - Write to .scratch/pr-bodies/drafts/<slug>.md
- - Show draft to user: "Here's the draft PR. Does this look good?"
- - Allow edits before creating
-
- ☐ Create PR
- - gh pr create --title "..." --body-file .scratch/pr-bodies/drafts/<slug>.md
- - Capture PR number from output
-
- ☐ Archive and track
- - mkdir -p .scratch/pr-bodies/<number>/
- - mv draft to <number>/<timestamp>-body.md
- - Write metadata.json with hash of generated body
- - rm .scratch/pr-bodies/drafts/<slug>.md
- ```
-
- ### 2. Update PR Body
-
- ```
- ☐ Verify PR exists
- - gh pr view --json number,body,title,state
- - Load metadata.json if exists
- - Check state (error if closed/merged unless user confirms)
-
- ☐ Detect manual edits
- - Hash current body: echo "$body" | shasum -a 256
- - Compare to last_generated_hash in metadata
- - If differs:
- * Compute diff: diff <(echo "$last_generated") <(echo "$current")
- * Analyze: whitespace-only vs content changes
- * If material: show diff, ask "Overwrite manual edits, merge, or cancel?"
-
- ☐ Check for material changes
- - Re-analyze full commit range: <base>..HEAD
- - Compare to previous analysis
- - If no material change:
- * "The current PR description is still accurate."
- * Skip update unless user forces
-
- ☐ Generate updated body
- - Follow same content guidelines as create
- - Re-analyze all commits in range
-
- ☐ Draft review
- - Write to .scratch/pr-bodies/<number>/<timestamp>-body.md
- - Show diff: current vs proposed
- - "Here's what would change. Look good?"
-
- ☐ Update PR
- - gh pr edit <number> --body-file <file>
- - Update metadata.json (hash, timestamp, manual_edits_detected)
- ```
-
- ### 3. Add PR Comment
-
- ```
- ☐ Verify PR exists
- - gh pr view --json number,title,reviews,comments
- - Check for review activity
-
- ☐ Determine comment content
- - Analyze recent commits since last update
- - Focus on: what changed and why
- - Common scenarios:
- * Responding to review feedback
- * Noting significant additions after initial review
- * Summarizing a batch of changes
-
- ☐ Draft comment
- - Write to .scratch/pr-bodies/<number>/<timestamp>-comment.md
- - Tone: conversational, helpful, concise (3-5 sentences)
- - Structure: "I've updated the PR to address..."
- - Show draft to user
-
- ☐ Post comment
- - gh pr comment <number> --body-file <file>
- - Optional: Update metadata.json with comment timestamp
- ```
-
- ## Decision Matrix: Update Body vs Comment
+ ## Overview
- **Prefer UPDATE BODY when:**
+ Authoring PR communication that respects busy reviewers. All bodies and comments are drafted to `.scratch/pr-bodies/` for human review before posting. Anti-patterns (metrics, diff-noise, H1 headings) are avoided. Manual edits are detected before overwriting.
- - PR has no reviews/comments yet
- - User explicitly says "update description/body"
- - Material scope change that needs description rewrite
+ ## Operations
- **Prefer COMMENT when:**
+ | Operation | Typical phrasing | gh command at end |
+ |---|---|---|
+ | Create | "create/draft/open/file a PR", "push and PR it" | `gh pr create --body-file` |
+ | Update body | "update the PR body", "rewrite the PR description" | `gh pr edit --body-file` |
+ | Comment | "comment on the PR", "reply to review feedback" | `gh pr comment --body-file` |
- - PR has review activity (comments, requested changes)
- - User mentions "responding to feedback"
- - Batch of changes after initial review
- - Want to notify watchers (comments generate notifications, body updates don't)
+ ## Routing ambiguous requests
- ## Content Guidelines
+ "update the PR" is ambiguous:
- ### PR Title Format
+ - No PR exists: error and offer to create
+ - PR has no reviews: update body
+ - PR has reviews: ask whether to update body or add a comment
- - **Imperative mood:** "Add", "Fix", "Update", "Refactor"
- - **Concise:** < 72 characters ideal
- - **Capitalize** first word
- - **No period** at end
- - **Derive from:** Branch name (if semantic) or first commit message
+ Prefer **body update** when there are no reviews yet, the user says "update the description", or scope changed. Prefer **comment** when reviews are in, the user is responding to feedback, or they want to notify watchers (comments generate notifications, body updates do not).
- ### PR Body Structure
+ ## Content principles
- **When PR template exists:**
+ ### Follow repo conventions first
- - Follow template structure exactly
- - Fill sections based on commit analysis
- - Preserve template comments/instructions
+ Check for a PR template (`.github/pull_request_template.md`, `.github/PULL_REQUEST_TEMPLATE.md`, `.github/PULL_REQUEST_TEMPLATE/*.md`) and `CONTRIBUTING.md` (also `.github/CONTRIBUTING.md`, `docs/CONTRIBUTING.md`). If a template exists, follow it exactly.
- **When no template exists:**
+ ### Default body structure (no template)
```markdown
## Summary
- Material impact point 1
- - Material impact point 2
- - Material impact point 3 (if needed)
+ - Material impact point 2 (2-4 bullets total)
## Test plan
- - How to verify the changes work
- - Only if non-obvious or requires manual testing
-
- [Optional sections based on context:]
-
- ## Breaking changes
-
- ## Migration notes
-
- ## Follow-up work
- ```
-
- ### Content Principles
-
- **✅ DO:**
-
- - Focus on material impact: "Enables pattern-based Spotlight exclusions for easier maintenance"
- - Be concise yet warm: "This makes it easier to manage exclusions at scale."
- - Explain why it matters, what problem it solves
- - Include non-obvious testing steps
-
- **❌ DON'T - Common Anti-Patterns:**
-
- **Metrics (unless PR is specifically about them):**
- - ❌ "Added 15 tests" → ✅ "Added test coverage for edge cases"
- - ❌ "Modified 8 files across 3 modules" → ✅ Say nothing (diff shows this)
- - ❌ "Reduced runtime from 2.5s to 1.2s" → ✅ Only if PR is about performance
- - ❌ "Added 250 lines of code" → ✅ Never mention line counts
- - ❌ "Test coverage increased to 85%" → ✅ Only if PR is about coverage
-
- **Implementation details visible in diff:**
- - ❌ "Created new `PatternExpander` class" → ✅ Say nothing (diff shows this)
- - ❌ "Refactored into smaller functions" → ✅ Say nothing unless it's the PR's focus
- - ❌ "Used async/await pattern" → ✅ Say nothing (implementation detail)
- - ❌ "Added error handling" → ✅ Only if error handling is the PR's focus
-
- **Over-explaining/verbose:**
- - ❌ "This change significantly improves the developer experience by implementing a novel approach..."
- - ✅ "Makes it easier to maintain exclusions at scale"
- - ❌ "After careful consideration of multiple approaches, we decided to..."
- - ✅ Just describe what it does and why it matters
-
- **Other common mistakes:**
- - ❌ Use H1 heading (GitHub shows title separately, causes duplication)
- - ❌ List technologies used unless it's a new dependency worth noting
- - ❌ Describe file structure changes unless it's an architectural shift
- - ❌ Mention "following best practices" (assumed)
- - ❌ Say "easy to" or "simple to" (condescending)
-
- **The rule:** If a reviewer can see it in the diff or CI output, don't put it in the PR body unless it's the central focus of the PR.
-
- ### Following Repository Guidelines
-
- **Search for PR templates:**
-
- ```
- - .github/pull_request_template.md
- - .github/PULL_REQUEST_TEMPLATE.md
- - .github/PULL_REQUEST_TEMPLATE/*.md
- ```
-
- **Search for CONTRIBUTING.md:**
-
- ```
- - CONTRIBUTING.md
- - .github/CONTRIBUTING.md
- - docs/CONTRIBUTING.md
- ```
-
- **If found:** Extract PR-related guidance (required info, checklists, style) and incorporate into body generation.
-
- ### Comment Content Guidelines
-
- **Structure:**
-
- ```markdown
- I've updated the PR to address the feedback:
-
- - Point about what changed
- - Another significant change
- - Why these changes were made
-
- [Optional: specific response to review comment if relevant]
+ - How to verify (only if non-obvious)
```
- **Tone:**
-
- - Conversational but professional
- - Acknowledge reviewers' input
- - Explain reasoning when non-obvious
- - Keep brief (3-5 sentences typical)
-
- ## Error Handling & Edge Cases
-
- ### Safety Checks
+ Optional sections based on context: `## Breaking changes`, `## Migration notes`, `## Follow-up work`.
- **Before creating PR:**
+ ### PR title
- - ✓ Current branch is not main/master
- - ✓ Branch has commits ahead of base
- - ✓ gh CLI is installed and authenticated
- - ✓ User has reviewed draft
+ Imperative mood (Add, Fix, Update, Refactor), under 72 characters, capitalize first word, no trailing period. Derive from the branch name when semantic, otherwise from the first commit.
- **Before updating PR body:**
+ ### Do
- - ✓ PR exists and is open (warn if closed/merged)
- - ✓ Manual edits check complete
- - ✓ User has reviewed diff
+ - Focus on material impact and why it matters
+ - Include non-obvious testing steps
+ - Stay warm and concise
- **Before posting comment:**
+ ### Don't
- - ✓ PR exists
- - ✓ Comment is not empty
- - ✓ User has reviewed content
+ **Metrics** (unless the PR is about them): "Added 15 tests", "Modified 8 files", "Added 250 lines", "Coverage to 85%", "Runtime 2.5s to 1.2s".
- ### Common Errors
+ **Diff-visible details**: "Created new `Foo` class", "Refactored into smaller functions", "Used async/await", "Added error handling" (unless that is the PR's focus).
- **No PR exists (when updating/commenting):**
+ **Over-explaining**: "After careful consideration of multiple approaches...", "significantly improves the developer experience by implementing a novel approach...".
- ```
- Error: "No PR found for branch '<branch-name>'.
- Would you like to create one?"
+ **Structural noise**: H1 heading (GitHub shows the title separately), listing technologies unless a new dependency, file structure changes unless architectural, "following best practices" (assumed), "easy to" / "simple to" (condescending).
- Action: Offer to route to create flow
- ```
+ **The rule:** If a reviewer can see it in the diff or CI output, do not put it in the body unless it is the central focus.
- **Multiple PRs for branch:**
+ ### Comment tone
- ```
- 1. gh pr list --head <branch> --state open
- 2. If exactly 1 open PR → use it
- 3. If 0 open PRs:
- - Check: gh pr list --head <branch> --state all
- - "No open PR found. Last PR was #123 (closed/merged)."
- - Offer to create new PR
- 4. If >1 open PR (rare):
- - "Found multiple open PRs: #123, #456. Which one?"
- ```
+ Three to five sentences, conversational, professional. Acknowledge reviewer input. Explain reasoning when non-obvious. A common opening pattern: "I've updated the PR to address the feedback: ..."
- **Not on a branch / on main:**
+ ## Workflow: Create PR
- ```
- Error: "Currently on '<branch>'.
- PRs should be created from feature branches, not main/master."
+ 1. Check for existing PR: `gh pr view --json number 2>/dev/null`. If one exists, error or route to update.
+ 2. Gather: `git log <base>..HEAD`, PR template, `CONTRIBUTING.md`.
+ 3. Draft body to `.scratch/pr-bodies/drafts/<slug>.md`. Show the draft to the user and allow edits.
+ 4. Create: `gh pr create --title "..." --body-file <draft-path>` (add `--draft` if the user asked for a draft).
+ 5. Archive: move the draft to `.scratch/pr-bodies/<number>/<timestamp>-body.md` and write `metadata.json` with the body hash.
- Action: Stop, suggest creating a branch first
- ```
+ ## Workflow: Update body
- **gh CLI not available:**
+ 1. Load: `gh pr view --json number,body,title,state`. Load `metadata.json` if present. Warn if closed or merged.
+ 2. Detect manual edits: hash the current body (`shasum -a 256`) and compare to `last_generated_hash`. If different and the diff is more than whitespace, ask: overwrite, merge, or cancel.
+ 3. Check for material change: re-analyze `<base>..HEAD`. If scope is unchanged from last generation, skip the update and say "description still accurate".
+ 4. Draft to `.scratch/pr-bodies/<number>/<timestamp>-body.md`. Show the diff (current vs proposed) and confirm.
+ 5. Update: `gh pr edit <number> --body-file <file>`. Update `metadata.json` (new hash, timestamp).
- ```
- Error: "GitHub CLI (gh) not found. Install with: brew install gh"
- ```
+ ## Workflow: Comment
- **gh not authenticated:**
+ 1. Load: `gh pr view --json number,title,reviews,comments`.
+ 2. Determine content. Analyze recent commits. Common scenarios: responding to review feedback, noting significant additions, summarizing a batch of changes.
+ 3. Draft to `.scratch/pr-bodies/<number>/<timestamp>-comment.md`. Show the draft and confirm.
+ 4. Post: `gh pr comment <number> --body-file <file>`.
- ```
- Error: "GitHub CLI not authenticated. Run: gh auth login"
- ```
+ ## Safety checks
- ### Edge Cases
+ Always: current branch is not `main`/`master`; `gh` is installed and authenticated; the user has seen and approved the draft.
- **Manual edits detected:**
+ Create: branch has commits ahead of base. Update: PR exists and is open. Comment: comment is not empty.
- ```
- 1. Show diff: "The PR body has been manually edited. Here's what changed:"
- 2. Ask: "Overwrite manual edits, merge, or cancel?"
- - Overwrite: Replace with new generated body
- - Merge: Preserve manually-added sections
- - Cancel: Keep current body
- ```
+ If `gh` is missing, fall back with `brew install gh`. If not authenticated, `gh auth login`.
- **No material changes in update:**
+ ## Storage layout
```
- "Analyzed commits - no material changes to scope or impact.
- The current PR description is still accurate."
-
- Action: Skip update unless user forces
+ .scratch/pr-bodies/
+ drafts/
+ <slug>.md # Pre-creation drafts
+ <pr-number>/
+ metadata.json # See schema below
+ <timestamp>-body.md # Timestamped body versions
+ <timestamp>-comment.md # Timestamped comments
```
- **Draft in progress:**
+ `metadata.json`:
- ```
- "Found existing draft for '<title>'.
- Use existing draft, create new, or cancel?"
+ ```json
+ {
+ "pr_number": 123,
+ "branch": "feature/foo",
+ "base": "main",
+ "title": "Add foo",
+ "created_at": "2025-11-07T10:30:00Z",
+ "last_generated_hash": "abc123...",
+ "last_updated_at": "2025-11-07T16:45:30Z",
+ "manual_edits_detected": false
+ }
```
- **Scratch directory doesn't exist:**
+ Timestamps use ISO 8601 with hyphens (`2025-11-07T10-30-00`). Slugs are lowercase with hyphens and special chars stripped.
- ```
- mkdir -p .scratch/pr-bodies/drafts
- ```
+ Keep: `metadata.json`, the last five timestamped files, any in-progress draft. Clean up after PR creation: the draft file. Optional: timestamped files older than 30 days.
- ## Change Detection Algorithm
+ ## Base branch detection
```bash
- # 1. Quick hash check
- current_hash=$(gh pr view body -q .body < number > --json | shasum -a 256)
- last_hash=$(jq -r .last_generated_hash .scratch/pr-bodies/ < number > /metadata.json)
-
- # 2. If hashes match → no changes
- if [ "$current_hash" = "$last_hash" ]; then
- echo "No manual edits detected"
- exit 0
+ base=$(gh pr view --json baseRefName -q .baseRefName 2>/dev/null)
+ if [ -z "$base" ]; then
+ git show-ref --verify --quiet refs/heads/main && base=main || base=master
fi
-
- # 3. If hashes differ → compute diff
- gh pr view body -q .body < number > --json > /tmp/current.md
- cat .scratch/pr-bodies/ < number > / < last-timestamp > -body.md > /tmp/last.md
- diff -u /tmp/last.md /tmp/current.md
-
- # 4. Analyze diff
- # - Whitespace only? → Not material
- # - Content changes? → Material, set manual_edits_detected = true
```
- ## Integration with Other Skills
-
- **working-in-scratch-areas:**
-
- - All drafts go to `.scratch/pr-bodies/`
- - Auto-creates directory structure
-
- **git-preferences-and-practices:**
-
- - Respects git workflow preferences
- - Works with branch naming conventions
-
- **Repository conventions:**
-
- - Checks for ADRs and references them
- - Links to docs/plans if design doc exists
-
- ## Example Workflows
-
- ### Creating a PR
-
- ```
- User: "create a PR for this branch"
-
- Claude: "I'm using the gh-pr skill to create the pull request."
- [Analyzes commits: 5 commits adding spotlight exclusion patterns]
- [Checks for templates: none found]
- [Generates draft in .scratch/pr-bodies/drafts/add-spotlight-patterns.md]
-
- Claude: "Here's the draft PR. The summary focuses on the pattern-based
- approach and easier maintenance. Does this look good?"
-
- [Shows draft content]
-
- User: "yes"
-
- Claude: [Creates PR #123]
- "Created PR #123: Add spotlight exclusion patterns
- https://github.com/user/repo/pull/123"
- ```
-
- ### Updating After Changes
-
- ```
- User: "update the PR"
-
- Claude: "I'm using the gh-pr skill to update the pull request."
- [Checks PR #123]
- [Hash check: no manual edits]
- [Analyzes commits: 3 new commits adding monitoring tools]
-
- Claude: "I've added 3 commits since the PR was created. The scope has
- expanded to include monitoring tools. Should I update the description?"
-
- User: "yes"
-
- Claude: [Generates new body]
- "Here's what would change in the description:
-
- + ## Monitoring
- + Includes live monitoring and activity analysis tools
-
- Look good?"
-
- User: "yes"
-
- Claude: [Updates PR]
- "Updated PR #123 description"
- ```
-
- ### Adding a Comment
-
- ```
- User: "comment on the PR about the changes"
-
- Claude: "I'm using the gh-pr skill to comment on the pull request."
- [Checks PR #123: has 2 review comments]
-
- Claude: "This PR has review comments. I'll add a comment about the
- recent updates. Here's the draft:
-
- ---
- I've updated the PR to address the feedback:
- - Added input validation for pattern file paths
- - Improved error messages for invalid patterns
- - Updated tests to cover edge cases
-
- The validation now catches malformed patterns before attempting expansion.
- ---
-
- Look good?"
-
- User: "yes"
-
- Claude: [Posts comment]
- "Added comment to PR #123"
- ```
-
- ## File Management
-
- **Keep:**
-
- - metadata.json (permanent record)
- - Last 5 timestamped bodies/comments
- - Current draft (if in progress)
-
- **Clean up:**
-
- - Completed drafts after PR creation
- - Old timestamped files (optional: >30 days)
-
- ## Implementation Notes
-
- **Hash algorithm:** Use `shasum -a 256` for consistency
-
- **Timestamp format:** ISO 8601 with hyphens for filenames: `2025-11-07T10-30-00`
-
- **Slugification:** Lowercase, hyphens, strip special chars: "Add Spotlight Skill" → "add-spotlight-skill"
+ ## Multiple PRs for one branch
- **Base branch detection:**
+ `gh pr list --head <branch> --state open`. If exactly one open, use it. If zero, check `--state all` and offer to create new. If more than one (rare), ask which.
- ```bash
- # Try to detect from gh pr view first
- base=$(gh pr view --json baseRefName -q .baseRefName 2> /dev/null)
+ ## Common mistakes
- # Fall back to common defaults
- if [ -z "$base" ]; then
- if git show-ref --verify --quiet refs/heads/main; then
- base="main"
- else
- base="master"
- fi
- fi
- ```
+ - Posting the first draft without user review. Always confirm before running `gh pr create/edit/comment`.
+ - Overwriting manual edits silently. Always compare hashes and show the diff first.
+ - Updating body when nothing material changed. Skip with "description still accurate".
+ - Using raw `gh pr create` without `--body-file`. Shell-escaping issues and no draft review step.
+ - Running create on `main`/`master`. Stop and ask the user to branch first.
+ - Ignoring repeated open PRs on the same branch. Always check `gh pr list --head <branch>`.