Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Uploads a local file (screenshot, image, PDF, zip, video) to GitHub user-attachments, downloads GitHub user-attachments, and embeds local files in a PR, issue, or comment. Use when asked to "attach a screenshot to the PR", "add an image to the issue", "embed before/after screenshots", "attach this file", or "download this GitHub attachment". Powered by `gh-attach`.
.claude/skills/github-gh-attach/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -79% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 323% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -52% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -55% | 0% |
| case-06 | ✗→✓ | ▲ Improved | -50% | 0% |
gh attach uploads a file to GitHub's internal user-attachments endpoint (no public API exists) and prints the URL, which GitHub auto-renders (image/video/file) wherever it's pasted. The URL inherits the repo's visibility, so private-repo uploads stay private.
shgh extension list | grep -q 'gh attach' || gh extension install sudosubin/gh-attach
Uploads use a GitHub browser session cookie, not the gh token. By default, gh must be authenticated so gh-attach can select the matching browser account. If the wrong account is selected, add --browser <name> --profile <name>. For headless use, set GH_ATTACH_SESSION_TOKEN to the bare user_session cookie value. Treat it as a full account credential.
1. Upload: Use an absolute quoted path. -R is optional inside a repository. For GHES, use -R host/owner/repo. The command prints the URL on one line. GitHub auto-renders it (image/video/file), so use it as-is:
shURL=$(gh attach "$FILE" -R <owner>/<repo>)
2. Embed (always --body-file -, e.g. gh pr comment/edit, gh issue comment/edit):
shprintf '## Screenshots\n\n%s\n' "$URL" | gh pr comment <pr> -R <owner>/<repo> --body-file -
3. Download: Specify the destination explicitly. Private attachments use the active gh token, with browser cookies as an authorization fallback:
shgh attach download "$URL" -O "$FILE"
<img width="800" src="$URL"> instead of the bare URL.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 36,378 | 18,025 | -50% | 1 | 1 | 0% | 5,326 | 1,134 | -79% | 0 | 0 | — |
case-02 | fail→pass | 5,200 | 4,306 | -17% | 1 | 1 | 0% | 239 | 1,011 | +323% | 0 | 0 | — |
case-03 | fail→pass | 12,272 | 2,651 | -78% | 1 | 1 | 0% | 1,684 | 801 | -52% | 0 | 0 | — |
case-04 | pass→pass | 7,935 | 5,418 | -32% | 1 | 1 | 0% | 1,278 | 1,160 | -9% | 0 | 0 | — |
case-05 | fail→pass | 12,358 | 3,684 | -70% | 1 | 1 | 0% | 1,839 | 825 | -55% | 0 | 0 | — |
case-06 | fail→pass | 10,294 | 2,526 | -75% | 1 | 1 | 0% | 1,743 | 875 | -50% | 0 | 0 | — |
case-07 | fail→pass | 8,035 | 12,766 | +59% | 1 | 1 | 0% | 1,535 | 958 | -38% | 0 | 0 | — |
case-08 | pass→pass | 4,144 | 3,710 | -10% | 1 | 1 | 0% | 615 | 1,012 | +65% | 0 | 0 | — |
case-09 | fail→pass | 7,891 | 3,871 | -51% | 1 | 1 | 0% | 1,203 | 1,178 | -2% | 0 | 0 | — |
case-18 | pass→pass | 12,985 | 2,260 | -83% | 1 | 1 | 0% | 2,114 | 791 | -63% | 0 | 0 | — |
case-10 | pass→pass | 4,542 | 4,125 | -9% | 1 | 1 | 0% | 777 | 1,049 | +35% | 0 | 0 | — |
case-11 | pass→pass | 8,412 | 2,993 | -64% | 1 | 1 | 0% | 1,179 | 697 | -41% | 0 | 0 | — |
case-12 | pass→pass | 15,852 | 2,632 | -83% | 1 | 1 | 0% | 1,991 | 794 | -60% | 0 | 0 | — |
case-13 | pass→pass | 9,879 | 2,868 | -71% | 1 | 1 | 0% | 1,408 | 890 | -37% | 0 | 0 | — |
case-19 | fail→pass | 6,114 | 2,495 | -59% | 1 | 1 | 0% | 886 | 854 | -4% | 0 | 0 | — |
case-14 | fail→pass | 11,933 | 1,927 | -84% | 1 | 1 | 0% | 2,057 | 752 | -63% | 0 | 0 | — |
case-15 | fail→pass | 15,060 | 9,140 | -39% | 1 | 1 | 0% | 1,922 | 1,965 | +2% | 0 | 0 | — |
case-16 | pass→pass | 14,086 | 2,020 | -86% | 1 | 1 | 0% | 1,994 | 669 | -66% | 0 | 0 | — |
case-17 | pass→pass | 8,601 | 2,898 | -66% | 1 | 1 | 0% | 1,223 | 800 | -35% | 0 | 0 | — |
case-20 | pass→pass | 6,758 | 3,760 | -44% | 1 | 1 | 0% | 928 | 1,130 | +22% | 0 | 0 | — |
case-21 | pass→pass | 3,979 | 4,531 | +14% | 1 | 1 | 0% | 680 | 1,087 | +60% | 0 | 0 | — |
case-22 | fail→pass | 2,930 | 3,479 | +19% | 1 | 1 | 0% | 515 | 925 | +80% | 0 | 0 | — |
case-23 | pass→pass | 7,374 | 2,726 | -63% | 1 | 1 | 0% | 1,074 | 856 | -20% | 0 | 0 | — |
case-24 | fail→pass | 6,016 | 2,540 | -58% | 1 | 1 | 0% | 1,065 | 900 | -15% | 0 | 0 | — |
case-25 | fail→pass | 29,234 | 1,926 | -93% | 1 | 1 | 0% | 4,711 | 762 | -84% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted, and 24 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +52 percentage points is the difference between those two pass rates over the 24 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.