Skip to content

Commit c8a50e3

Browse files
committed
feat: add portable PR attachment skill
1 parent f4b2a72 commit c8a50e3

3 files changed

Lines changed: 41 additions & 0 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
name: attach-github-pr-files
3+
description: Upload local images or files and embed them in a GitHub pull request body or comment. Use when a PR needs a screenshot, log, PDF, or other attachment that GitHub CLI, Codex, or Claude Code cannot upload directly.
4+
---
5+
6+
Run this skill's `scripts/upload.sh FILE [ALT]`; paste its Markdown output into the PR.
7+
8+
Require `GITHUB_ATTACHMENTS_TOKEN`. Give images meaningful alt text.
9+
10+
Never upload secrets: anyone with the URL can read the file until it expires.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
interface:
2+
display_name: "Attach GitHub PR Files"
3+
short_description: "Upload files for GitHub pull request Markdown"
4+
default_prompt: "Use $attach-github-pr-files to attach this file to the GitHub pull request."
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/sh
2+
set -eu
3+
4+
file=${1:?"usage: upload.sh FILE [ALT]"}
5+
alt=${2-}
6+
: "${GITHUB_ATTACHMENTS_TOKEN:?GITHUB_ATTACHMENTS_TOKEN is required}"
7+
test -f "$file"
8+
9+
output=$(mktemp)
10+
trap 'rm -f "$output"' EXIT HUP INT TERM
11+
12+
set -- \
13+
--fail-with-body --silent --show-error \
14+
--request POST \
15+
--header "Authorization: Bearer $GITHUB_ATTACHMENTS_TOKEN" \
16+
--header "X-Filename: $(basename "$file")" \
17+
--header "Content-Type: $(file --brief --mime-type -- "$file")" \
18+
--data-binary "@$file" \
19+
--output "$output"
20+
[ -z "$alt" ] || set -- "$@" --header "X-Alt-Text: $alt"
21+
22+
if ! curl "$@" https://github-pr-attachments.none23.workers.dev/v1/attachments; then
23+
cat "$output" >&2
24+
exit 1
25+
fi
26+
27+
node -e 'const x=JSON.parse(require("fs").readFileSync(process.argv[1]));if(typeof x.markdown!=="string")throw Error("invalid response");console.log(x.markdown)' "$output"

0 commit comments

Comments
 (0)