* Add visual-pr plugin: screenshot capture, annotation, PR embedding, and screen recording Four skills that teach Copilot to capture UI screenshots (Playwright + PIL), annotate them with algorithmic label placement, embed before/after images in PR descriptions, and record animated GIF demos. Includes demo images showing the annotation engine on GitHub Issues. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update generated README tables and marketplace.json Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Embed annotate.py module in image-annotations skill The full working module (annotate_image, grid_image, diff_images) is now included as a code block so users can save it as annotate.py and import directly. Scrubbed project-specific labels from examples. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback: mss.mss() context manager, fix RECT struct, consistent placeholder - Use mss.mss() context manager instead of mss.MSS() (ui-screenshots, screen-recording) - Fix broken RECT struct in window+GIF combining example (screen-recording) - Consistent projectId placeholder in AzDO upload example (pr-screenshots) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4.8 KiB
name, description
| name | description |
|---|---|
| pr-screenshots | Embed before/after screenshots and annotated images in pull request descriptions. Covers PR description patterns, image upload for Azure DevOps and GitHub, and sizing best practices. |
PR Screenshots
Embed before/after screenshots in pull request descriptions so reviewers can see the visual change without checking out the branch.
When to Use This Skill
Use this skill when a PR changes something visible:
- Layout, styling, CSS
- Charts, dashboards, data visualizations
- UI components, forms, modals
- Error messages, CLI output, log formatting
PR Description Pattern
Place screenshots directly in the PR description body. Avoid wrapping them in <details> collapse — reviewers are more likely to look at images they can see without clicking.
**Before** — brief description of the problem:

**After** — brief description of the fix:

Keep the text brief. A sentence or two per image describing what the reader should notice. Let the image carry most of the communication.
Multiple changes
For PRs with several visual changes, use separate before/after pairs with headings:
## Filter bar alignment
**Before** — 1px border clash between adjacent buttons:

**After** — borders overlap cleanly, hover tint added:

## Chart tooltip
**Before** — tooltip clipped at container edge:

**After** — tooltip repositions to stay visible:

Image Sizing
- Take screenshots at native 1x resolution — don't resize with PIL (creates artifacts)
- Control display size in HTML when images are too large:
<img src="url" width="600" alt="description"> - Before/after pairs must use the same viewport width and crop — otherwise the comparison is meaningless
Uploading Images
Azure DevOps
Upload images as PR attachments via the REST API:
$token = az account get-access-token `
--resource "499b84ac-1321-427f-aa17-267ca6975798" `
--query accessToken -o tsv
$base = "https://{org}.visualstudio.com/{projectId}/_apis/git/repositories/{repoId}"
$url = "$base/pullRequests/{prId}/attachments/screenshot.png?api-version=7.1-preview.1"
# Use HttpClient — Invoke-RestMethod can corrupt binary data
$client = New-Object System.Net.Http.HttpClient
$client.DefaultRequestHeaders.Authorization = `
New-Object System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $token)
$content = New-Object System.Net.Http.ByteArrayContent(
, [System.IO.File]::ReadAllBytes("screenshot.png")
)
$content.Headers.ContentType = `
[System.Net.Http.Headers.MediaTypeHeaderValue]::new("application/octet-stream")
$resp = $client.PostAsync($url, $content).Result
Reference in the PR description:

Azure DevOps gotchas:
- Use
{org}.visualstudio.comNOTdev.azure.com/{org}— AzDO's markdown renderer uses.visualstudio.com. Thedev.azure.comformat loads noticeably slower - Use
POSTnotPUT(PUT returns 405) - API version must be
7.1-preview.1 - Can't re-upload with the same filename — use a new name (e.g.
screenshot-v2.png) - Use
HttpClientnotInvoke-RestMethod— IRM can corrupt binary data - Repo-relative paths don't work in PR descriptions — must use full URLs
- Don't commit images to the branch just for PR screenshots
GitHub
⚠️ Work in progress. GitHub's drag-and-drop image upload uses internal endpoints that require browser cookies. There's no clean public API for uploading images to PR descriptions yet.
Current workaround: Commit images to a pr-assets orphan branch and reference via blob URLs (github.com/{owner}/{repo}/blob/pr-assets/{file}?raw=true). It works but is clunky — contributions for a better approach are welcome.
Guidelines
- Capture before state BEFORE making changes — it's easy to forget, and reconstructing the original state later is slow and error-prone
- Keep descriptions brief — a sentence or two per image pointing out what changed is enough
- Prefer visible images over collapsed sections — screenshots behind
<details>tags are easy to skip - Annotate when the change is subtle — use the
image-annotationsskill to add callouts when the difference isn't immediately obvious - Match viewport and crop between before/after pairs so the comparison is meaningful
Limitations
- GitHub image upload requires workarounds (no public API for PR description images)
- Azure DevOps attachment filenames can't be reused — plan naming ahead
- Very large images (>10MB) may not render inline on some platforms