Loading...
Loading...
Upload local images to a GitHub PR and embed them in the description or comments. Use when asked to "attach screenshots to PR", "add images to PR", "upload test results to PR", "embed screenshots in PR description", "add before/after images to PR", "attach UI screenshots", "show test results in PR", "add visual evidence to PR", or any request involving images and PRs. Always use this skill when the user wants to visually document changes in a pull request, even if they don't use the word "upload" — phrases like "put the screenshot in the PR" or "show the image in the PR" should trigger this skill. Supports Playwright MCP / Chrome DevTools MCP / agent-browser as browser automation backends.
npx skill4agent add tonkotsuboy/github-upload-image-to-pr github-upload-image-to-pruser-attachments/assets/gh# Get PR number from the current branch
gh pr view --json number,url -q '"\(.number) \(.url)"'/tmp/# e.g., to handle glob-matched paths with special chars
cp /path/to/CleanShot*keyword*.png /tmp/screenshot.pngmcp__playwright__*mcp__chrome-devtools__*--profile--profile ~/.agent-browser-github# 1. Search for MCP-based browser tools (preferred)
ToolSearch: "browser navigate upload"
# 2. Fall back to agent-browser only if no MCP tools found
Bash: agent-browser --version| Operation | Playwright MCP | Chrome DevTools MCP | agent-browser (CLI/Bash) |
|---|---|---|---|
| Navigate | | | |
| Snapshot | | | |
| Screenshot | | | |
| Click | | | |
| File Upload | | | |
| JS Eval | | | |
| Login State | Preserved | Preserved | Preserved with |
// Playwright MCP
browser_navigate({ url: "https://github.com/{owner}/{repo}/pull/{number}" })
// Chrome DevTools MCP
navigate_page({ url: "https://github.com/{owner}/{repo}/pull/{number}", type: "url" })
// agent-browser (use --profile to persist login state)
agent-browser --headed --profile ~/.agent-browser-github open "https://github.com/{owner}/{repo}/pull/{number}"https://github.com/login// Shared JS for MCP-based tools — tries multiple known selectors
() => {
const selectors = [
'input[type="file"][id*="comment"]',
'input[type="file"][id="fc-new_comment_field"]',
'#new_comment_field',
'input[type="file"]'
];
for (const sel of selectors) {
const el = document.querySelector(sel);
if (el) return { found: true, id: el.id, selector: sel };
}
return { found: false };
}uid// Chrome DevTools MCP: upload_file requires the uid of the input element
// Playwright MCP: browser_file_upload takes the element ref and file path(s) array
// agent-browser: agent-browser upload {ref} {absolute_path}// Shared JS — tries both known textarea IDs
() => {
const ta = document.getElementById('new_comment_field')
|| document.querySelector('textarea[id*="comment"]');
return ta ? ta.value : 'textarea not found';
}# agent-browser
agent-browser eval 'document.getElementById("new_comment_field")?.value || document.querySelector("textarea[id*=comment]")?.value || "not found"'// MCP-based tools
() => {
const ta = document.getElementById('new_comment_field')
|| document.querySelector('textarea[id*="comment"]');
if (ta) { ta.value = ""; return "cleared"; }
return "textarea not found";
}# agent-browser
agent-browser eval 'const ta = document.getElementById("new_comment_field") || document.querySelector("textarea[id*=comment]"); if(ta){ta.value=""} "cleared"'EXISTING_BODY=$(gh pr view {PR_NUMBER} --json body -q .body)
gh pr edit {PR_NUMBER} --body "$(printf '%s\n\n## Screenshots\n\n%s' "$EXISTING_BODY" "")"gh pr comment {PR_NUMBER} --body "## Screenshots
"<img><img width="800" alt="description" src="..." />--profile ~/.agent-browser-github| Issue | Solution |
|---|---|
| Not logged in (MCP tools) | SSO screen may appear — take snapshot, find "Continue" button, click it |
| Not logged in (agent-browser) | Use |
| Browser window not visible | For agent-browser, ensure |
| File path with special characters (e.g., Unicode narrow spaces from CleanShot) | Copy file to |
| File upload fails | Ensure the file path is absolute |
| Textarea doesn't contain URLs yet | Wait 3–5 seconds after upload before running JS eval; retry once if needed |
| Textarea selector not found | GitHub UI changes occasionally — use the multi-selector JS in Step 2 to find the current element |
| Chrome DevTools MCP disconnected | Reconnect via |
| agent-browser not found | |
| No browser tools found | Use |
| PR not found / 404 | Private repos return 404 for unauthenticated users — check login state |
user-attachments/assets/gh pr edit