From gh-pr-image
Upload local images to a GitHub PR description or comment without committing them to the repo. Use when creating PRs that need before/after screenshots, visual diffs, or any embedded images.
How this skill is triggered — by the user, by Claude, or both
Slash command
/gh-pr-image:gh-pr-imageThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Upload local images (screenshots, diagrams, visual diffs) to a GitHub PR description without committing them to the repository. Uses GitHub release assets as a CDN — the only fully scriptable, CLI-only approach that works for private repos.
Upload local images (screenshots, diagrams, visual diffs) to a GitHub PR description without committing them to the repository. Uses GitHub release assets as a CDN — the only fully scriptable, CLI-only approach that works for private repos.
GitHub has no public API for uploading images to PR descriptions. The drag-and-drop upload in the web UI uses an undocumented endpoint (/upload/policies/assets) that requires browser session cookies — it cannot be called with an API token.
The available workarounds and their trade-offs:
| Approach | Works from CLI? | Private repos? | Downsides |
|---|---|---|---|
| Commit images to repo | Yes | Yes | Bloats the repo, images live forever in git history |
| Drag-and-drop on web | No | Yes | Manual, breaks CLI workflow |
| External host (S3, imgur) | Yes | N/A | Requires separate service, images may expire |
| Browser automation (gh-attach) | Partially | Yes | Requires Playwright + browser login session |
| Release assets (this skill) | Yes | Yes | Creates a prerelease tag in the repo |
browser_download_url for each assetRelease asset URLs are accessible to anyone with repo read access, making them work correctly in private repo PR descriptions.
# Variables
REPO="owner/repo" # or auto-detect from current directory
PR_NUMBER=137
TAG="pr-${PR_NUMBER}-images" # one tag per PR keeps things organized
# 1. Create prerelease with images attached
gh release create "$TAG" \
/tmp/before.png /tmp/after.png \
--repo "$REPO" \
--title "PR #${PR_NUMBER} screenshots" \
--notes "Image assets for PR #${PR_NUMBER}." \
--prerelease
# 2. Get the asset URLs
BEFORE_URL=$(gh api "repos/$REPO/releases/tags/$TAG" \
--jq '.assets[] | select(.name=="before.png") | .browser_download_url')
AFTER_URL=$(gh api "repos/$REPO/releases/tags/$TAG" \
--jq '.assets[] | select(.name=="after.png") | .browser_download_url')
# 3. Use in PR body
gh pr edit "$PR_NUMBER" --body "$(cat <<EOF
## Summary
Description here.
## Before

## After

EOF
)"
REPO="owner/repo"
TAG="pr-assets-$(date +%Y%m%d%H%M%S)"
FILE=/tmp/screenshot.png
gh release create "$TAG" "$FILE" \
--repo "$REPO" \
--title "PR screenshots" \
--notes "Image hosting for PRs." \
--prerelease
URL=$(gh api "repos/$REPO/releases/tags/$TAG" \
--jq ".assets[0].browser_download_url")
echo ""
If you want to reuse a single release as a persistent image store:
TAG="pr-assets"
# First time: create the release
gh release create "$TAG" \
--repo "$REPO" \
--title "PR image assets" \
--notes "Persistent image hosting for PR descriptions." \
--prerelease
# Subsequent uploads: add to existing release
gh release upload "$TAG" /tmp/new-screenshot.png --repo "$REPO"
URL=$(gh api "repos/$REPO/releases/tags/$TAG" \
--jq '.assets[] | select(.name=="new-screenshot.png") | .browser_download_url')
Prerelease tags can be cleaned up after PRs are merged:
# Delete a specific PR's image release
gh release delete "pr-137-images" --yes --cleanup-tag
# List all image releases
gh release list | grep "pr-.*-images"
gh CLI, authenticated (gh auth status)--prerelease so image-hosting releases don't appear as real releasespr-137-images) for easy cleanupnpx claudepluginhub mrshu/agent-skills --plugin gh-pr-imageUploads local images to GitHub and returns user-attachments embed URLs for use in PRs, issues, comments, or README files.
Creates GitHub issues with embedded images by uploading images as release assets and embedding them in the issue body. Works around GitHub CLI's lack of native image attachment support.
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.