craft-pr

Reads task files from tasks/<branch>/ and the diff against the detected base ref, then generates a polished PR description in markdown for the user to copy-paste.

SKILL.md

GitHub

Craft PR Description

You are generating a high-quality pull request description. Follow these steps strictly.

Extra context from the user

$ARGUMENTS

Step 1: Gather context

Step 1a: Resolve TASKS_DIR

Run this first using the Bash tool (step 1b depends on the output):

RAW_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
if [ -z "$RAW_BRANCH" ] || [ "$RAW_BRANCH" = "HEAD" ]; then
  SHORT_SHA=$(git rev-parse --short HEAD 2>/dev/null || echo "")
  RAW_BRANCH=${SHORT_SHA:+detached-$SHORT_SHA}
fi
if [ -z "$RAW_BRANCH" ]; then
  echo "Warning: not a git repo — using tasks/ as task directory" >&2
  TASKS_DIR="tasks"
else
  SANITIZED=$(echo "$RAW_BRANCH" | tr '/' '-' | tr -cs 'A-Za-z0-9._-' '-' | sed 's/^-*//; s/-*$//')
  [ -z "$SANITIZED" ] && SANITIZED="unknown-branch"
  TASKS_DIR="tasks/$SANITIZED"
fi
echo "BRANCH=$RAW_BRANCH"
echo "TASKS_DIR=$TASKS_DIR"

Step 1b: Gather diff + tasks in parallel

First resolve the base ref, then run the diff/log/task reads in parallel using the Bash tool (and Read/Glob for item 5):

  1. Resolve base ref — run first and store BASE_REF as a session variable

    BASE_REF=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/||')
    if [ -z "$BASE_REF" ] || ! git rev-parse --verify "$BASE_REF" >/dev/null 2>&1; then
      if git rev-parse --verify origin/main >/dev/null 2>&1; then
        BASE_REF=origin/main
      elif git rev-parse --verify main >/dev/null 2>&1; then
        BASE_REF=main
      else
        BASE_REF=HEAD~1
      fi
    fi
    echo "BASE_REF=$BASE_REF"
    
  2. Diff summary (stat) against $BASE_REF

    git diff --stat "$BASE_REF"...HEAD
    
  3. Full diff against $BASE_REF

    git diff "$BASE_REF"...HEAD
    
  4. Commit log since diverging from $BASE_REF

    git log --oneline "$BASE_REF"..HEAD
    
  5. Read all files in the branch-scoped task directory using the Read tool (read every .md file found via Glob $TASKS_DIR/*.md, using the TASKS_DIR resolved in step 1a). If $TASKS_DIR does not exist or contains no .md files, note this in the PR description — the tasks directory may have been cleaned up after the run.

Step 2: Analyze

From the gathered context, identify:

  • What changed: features added, bugs fixed, refactors done
  • Why it changed: map changes back to task files when possible
  • Scope: which apps/packages were touched
  • Risk areas: migrations, API changes, new dependencies, config changes
  • PR type: determine if this is a feature PR (adds new user-facing functionality), a bug-fix PR, a refactor, etc.

Step 2b: Feature discovery (feature PRs only)

If this is a feature PR, examine the diff and task files more deeply to identify every new user-facing feature. For each feature determine:

  1. What it does — a plain-language description of the feature from the end-user's perspective.
  2. Where it lives in the app — the route/page/section where the user can find it (e.g., "Sidebar → Outreach", "/intel/settings page", "new cron job at /api/cron/...").
  3. How to use it — brief step-by-step or description of the interaction flow (e.g., "Click 'Generate Hook', fill in the form, and the AI will produce a hook for the deal").

Read any new page/component files from the diff if needed to accurately describe navigation and usage.

Step 3: Generate the PR description

Output a single markdown block the user can copy-paste. Use this template:

## Summary

<!-- 2-4 sentence high-level overview of what this PR does and why -->

## Features

<!-- INCLUDE THIS SECTION ONLY FOR FEATURE PRs. Remove it entirely for bug-fix / refactor PRs. -->
<!-- For each new user-facing feature, describe what it does, where to find it, and how to use it. -->

### <Feature Name>
**Where:** <route / page / sidebar section where the user accesses this>
**What it does:** <plain-language description>
**How to use it:**
1. Step one
2. Step two
3. ...

### <Feature Name 2>
...

## Changes

<!-- Bulleted list of meaningful changes, grouped by area if needed -->

### <Area 1>
- Change description

### <Area 2>
- Change description

## Related Tasks

<!-- Link each task file that is relevant to the changes -->
- `task-01-...md` — brief description of what it covers
- `task-02-...md` — brief description of what it covers

## Risk & Review Notes

<!-- Anything reviewers should pay extra attention to -->
- ...

## Test Plan

<!-- How to verify these changes work -->
- [ ] ...
- [ ] ...

Rules

  • Keep the summary concise — no more than 4 sentences.
  • Features section: Only include for feature PRs. For each feature, always specify the concrete route/page/UI location and a clear usage flow. Read new page or component files if needed to get this right. Remove the section entirely for non-feature PRs.
  • In the Changes section, focus on what matters to a reviewer, not every single line changed. Group logically.
  • Only reference task files that are actually relevant to the diff. If a task has no matching changes, skip it.
  • If there are database migrations, flag them prominently in Risk & Review Notes.
  • If there are new environment variables or config changes, list them explicitly.
  • Output the final markdown inside a single fenced code block so the user can copy it easily.
  • Do NOT create a PR or push anything. Just output the description.