Skip to content

feat(bin): add skill for uploading evidence screenshots to GitHub - #1

Open
bkp5190 wants to merge 2 commits into
mainfrom
fm/github-pr-screenshot-skill-j2
Open

feat(bin): add skill for uploading evidence screenshots to GitHub#1
bkp5190 wants to merge 2 commits into
mainfrom
fm/github-pr-screenshot-skill-j2

Conversation

@bkp5190

@bkp5190 bkp5190 commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Intent

Create a skill for uploading screenshots to GitHub using the GitHub API (checking the API docs where possible). Background: crewmates working on stockmatch/stockmatch-infra/stockmatch-ios PRs already take real before/after screenshots as evidence, but they only ever referenced the local evidence file path (e.g. ~/.no-mistakes/evidence//after.png) in the PR description - that path is meaningless to anyone viewing the PR on GitHub, so the screenshots were never actually visible. Firstmate had just fixed this manually for three open PRs by uploading the existing local PNGs to GitHub and posting them as PR comments; the captain wants this turned into a reusable skill so future crewmates (and firstmate) do this automatically instead of it being a one-off manual fix. The captain was told GitHub has no officially documented API for uploading an image into a PR/issue body, but there is a working, undocumented uploads.github.com endpoint (POST https://uploads.github.com/user-attachments/assets?name=&content_type=&repository_id= with an Authorization: Bearer header and the file as the request body), which returns {"url": "https://github.com/user-attachments/assets/"} that renders inline when embedded as alt in a PR body or comment. The captain explicitly chose this undocumented-endpoint approach over the alternative of committing screenshots into the repo permanently, after being told the tradeoff - the endpoint being unofficial and able to break without notice is an accepted risk, not something to silently work around by switching approaches.

What Changed

  • Add .agents/skills/github-pr-screenshot/SKILL.md, an agent-only skill that uploads a local evidence screenshot to GitHub's attachment endpoint and embeds the returned URL as markdown so it renders inline on a PR, instead of referencing a local file path that's meaningless off the crewmate's machine.
  • Add bin/fm-pr-screenshot-upload.sh, the helper script backing the skill that performs the upload.
  • Wire the skill into AGENTS.md: section 11 now directs crewmate briefs that ask for evidence screenshots to use github-pr-screenshot instead of a bare local path, and section 13 registers it in the agent-only skill trigger list.
  • Register the new skill doc in docs/documentation-audiences.json under the agent-runtime audience.

Risk Assessment

✅ Low: The diff is a small, well-bounded skill+script addition; both previously authorized fixes (documentation-audiences entry, markdown alt-text escaping of ]) are correctly applied, shellcheck is clean, and tracing the upload script's logic (media-type detection, URL/query encoding, per-file error handling in a mixed batch) surfaced no new reachable bug.

Testing

Ran the targeted documentation-audiences regression test (passes, confirming the required audience-classification fix landed) and manually exercised bin/fm-pr-screenshot-upload.sh end-to-end against a real GitHub repository with push access, uploading a test PNG whose filename contains a literal ]: the script correctly escaped it in the markdown alt text and the real uploads.github.com endpoint returned a working asset URL that was verified (via authenticated fetch + byte comparison) to resolve back to the exact uploaded image, directly demonstrating the user's core intent — that a local screenshot becomes an actually-visible GitHub-hosted image. No findings.

Evidence: End-to-end upload verification transcript

Source: End-to-end upload verification transcript

End-to-end verification of bin/fm-pr-screenshot-upload.sh against a real GitHub repo (bkp5190/firstmate, push access confirmed).

Command:
  $ bash bin/fm-pr-screenshot-upload.sh bkp5190/firstmate "/tmp/fm-screenshot-test/before]after.png"

Output (note the `]` in the filename is correctly backslash-escaped in the markdown alt text,
confirming the review-2 fix for unescaped `]` producing malformed markdown):
  ![before\]after.png](https://github.com/user-attachments/assets/01d9d5ca-f7c7-4b28-ac4c-1ba571902afe)

Verification the returned URL is a genuine, working image asset:
  $ curl -H "Authorization: Bearer $(gh auth token)" -L \
      https://github.com/user-attachments/assets/01d9d5ca-f7c7-4b28-ac4c-1ba571902afe
  -> HTTP 302 redirect to a signed github-production-user-asset S3 URL
  -> downloaded bytes are byte-identical (cmp) to the originally uploaded PNG

This confirms the undocumented uploads.github.com/user-attachments/assets endpoint described in
.agents/skills/github-pr-screenshot/SKILL.md works exactly as documented end-to-end: a local
screenshot is uploaded, a rendering-capable github.com URL is returned, and that URL resolves back
to the exact uploaded image.

Also observed (informational, not a defect): an unreferenced attachment asset on this *public*
repo returned 404 to a fully anonymous curl request (no Authorization header) shortly after
upload, only succeeding once the request carried the gh auth Bearer token. This matches GitHub's
general user-attachments behavior of gating direct asset fetches behind an authenticated session
even on public repos; it does not affect inline rendering in an actual PR/issue body, which is
served through github.com's normal authenticated page-view context for any viewer with repo
access, consistent with the SKILL.md caveat about authenticated viewers.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

🔧 **Rebase** - 1 issue found → auto-fixed ✅

Push main to origin, or rebase your branch onto origin/main, before gating.

🔧 Fix applied.
✅ Re-checked - no issues remain.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • bash tests/fm-documentation-audiences.test.sh — all 4 subtests pass, confirming .agents/skills/github-pr-screenshot/SKILL.md is now classified in docs/documentation-audiences.json (resolves test-1/review-1)
  • Manual end-to-end run of bin/fm-pr-screenshot-upload.sh bkp5190/firstmate "before]after.png" against a real GitHub repo with confirmed push access: produced ![before\]after.png](https://github.com/user-attachments/assets/...) — bracket in filename correctly backslash-escaped in markdown alt text (resolves review-2)
  • Fetched the returned asset URL with an authenticated Bearer request: got a 302 to a signed S3 URL, downloaded content, and confirmed via cmp it is byte-identical to the originally uploaded PNG — proves the returned URL is a genuine, renderable image asset, not just an API artifact
  • git status --porcelain after testing — worktree left clean, no stray files
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Crewmates take real before/after evidence screenshots but only ever
referenced the local file path in PR descriptions, which is unreachable
from GitHub. Add a wrapper around the undocumented uploads.github.com
attachment endpoint plus a skill documenting when and how to use it,
and point future ship briefs at it instead of a bare local path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant