Describe the feature or problem you'd like to solve
Today gh has no first-party way to attach a local image file to an issue/PR comment body such that the image renders inline. For public repos, a contributor can work around this by pushing the file to the repo and embedding a raw.githubusercontent.com URL, but for private repos this path fails — GitHub's camo proxy cannot authenticate to private content, so raw.githubusercontent.com/<owner>/<repo>/<branch>/<file>.png renders as a broken image icon in every comment.
The only URL GitHub renders inline regardless of repo visibility is the one produced by the web-UI drag-drop upload flow: https://github.com/user-attachments/assets/<uuid>. Every gh-accessible alternative is blocked:
gh gist create file.png → failed to collect files for posting: failed to upload ...: binary file not supported.
gh api + POST https://github.com/upload/policies/assets with a PAT → HTTP 422 (endpoint is web-UI only, requires user_session cookie, not token auth).
- Third-party extensions like
enthus-appdev/gh-attach → no windows-amd64 binary and still rely on browser session cookies rather than gh auth token.
gh release upload → asset URLs for private repos require auth and don't render via camo.
The only path we could make work for a private-repo screenshot was: launch Playwright, sign in to github.com interactively, inject a helper <input type=\"file\">, populate it via the file chooser, and dispatch a drop event with a DataTransfer at the comment edit textarea so the web UI's own upload handler runs. That's a 10-step browser hack an agent or CI pipeline shouldn't need to reinvent.
Proposed solution
Add a first-party flag or subcommand that uploads a local file to GitHub's user-attachments CDN and returns the resulting https://github.com/user-attachments/assets/<uuid> URL. Shape options:
A standalone command:
gh attachment upload ./screenshot.png
# -> https://github.com/user-attachments/assets/37948111-1227-4cdb-a76d-dc8eb469ae5c
Or folded into the existing comment / create commands:
gh issue comment <number> --attach ./screenshot.png --body "……"
gh pr comment <number> --attach ./screenshot.png --body "……"
gh issue create --attach ./screenshot.png --body "……"
Benefits:
- Works uniformly for public and private repos (same CDN URL shape).
- Unblocks CI pipelines, bots, and
gh-driven agent tooling that want to attach screenshots to comments.
- Removes the per-team reinvention of cookie-based workarounds.
- Brings parity with the web-UI drag-drop flow users already know.
Implementation notes:
- If the underlying HTTP endpoint (
/upload/policies/assets or its successor) doesn't accept PAT/OAuth today, this likely needs a new REST/GraphQL surface on the GitHub API side first. If that's the real blocker, labeling this as an API dependency would at least tell users where the ask should move.
- Token scope should stay minimal — image upload tied to a specific repo context is sufficient.
Additional context
Real-world trigger: an automated agent was asked to include a Playwright screenshot in a private-repo issue comment. After exhausting raw.githubusercontent.com, gh gist create, the /upload/policies/assets endpoint, and the third-party gh-attach extension (no Windows binary), the only working path was to drive a full signed-in browser session through Playwright and hand-dispatch drop events. A first-party gh surface that returns a user-attachments URL would collapse that to a single command.
Describe the feature or problem you'd like to solve
Today
ghhas no first-party way to attach a local image file to an issue/PR comment body such that the image renders inline. For public repos, a contributor can work around this by pushing the file to the repo and embedding araw.githubusercontent.comURL, but for private repos this path fails — GitHub's camo proxy cannot authenticate to private content, soraw.githubusercontent.com/<owner>/<repo>/<branch>/<file>.pngrenders as a broken image icon in every comment.The only URL GitHub renders inline regardless of repo visibility is the one produced by the web-UI drag-drop upload flow:
https://github.com/user-attachments/assets/<uuid>. Everygh-accessible alternative is blocked:gh gist create file.png→failed to collect files for posting: failed to upload ...: binary file not supported.gh api+POST https://github.com/upload/policies/assetswith a PAT → HTTP 422 (endpoint is web-UI only, requiresuser_sessioncookie, not token auth).enthus-appdev/gh-attach→ nowindows-amd64binary and still rely on browser session cookies rather thangh auth token.gh release upload→ asset URLs for private repos require auth and don't render via camo.The only path we could make work for a private-repo screenshot was: launch Playwright, sign in to github.com interactively, inject a helper
<input type=\"file\">, populate it via the file chooser, and dispatch adropevent with aDataTransferat the comment edit textarea so the web UI's own upload handler runs. That's a 10-step browser hack an agent or CI pipeline shouldn't need to reinvent.Proposed solution
Add a first-party flag or subcommand that uploads a local file to GitHub's user-attachments CDN and returns the resulting
https://github.com/user-attachments/assets/<uuid>URL. Shape options:A standalone command:
Or folded into the existing comment / create commands:
Benefits:
gh-driven agent tooling that want to attach screenshots to comments.Implementation notes:
/upload/policies/assetsor its successor) doesn't accept PAT/OAuth today, this likely needs a new REST/GraphQL surface on the GitHub API side first. If that's the real blocker, labeling this as an API dependency would at least tell users where the ask should move.Additional context
Real-world trigger: an automated agent was asked to include a Playwright screenshot in a private-repo issue comment. After exhausting
raw.githubusercontent.com,gh gist create, the/upload/policies/assetsendpoint, and the third-partygh-attachextension (no Windows binary), the only working path was to drive a full signed-in browser session through Playwright and hand-dispatch drop events. A first-partyghsurface that returns auser-attachmentsURL would collapse that to a single command.