Skip to content

Latest commit

 

History

566 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

uploads.sh — the missing upload command for coding agents

uploads

The missing upload command for coding agents.

A lightweight file-hosting service on Cloudflare Workers. Agents capture screenshots as they work. When the pull request opens, all screenshots appear in one tidy comment that updates automatically on each revision. Built on files-sdk so the storage layer is provider-agnostic (R2 today; any files-sdk adapter later).

uploads.sh  ·  Docs  ·  npm →  ·  Use it  ·  What it looks like  ·  What's in this repo  ·  Develop

skills.sh CI npm (CLI) GitHub App: uploads-sh Ask DeepWiki License: Apache 2.0

Under active development. uploads.sh is being built in the open, so APIs (including auth) can still change. Feedback is welcome — open an issue.


What is this?

You add a screenshot to GitHub by dragging it into the comment box. Agents can't — GitHub's native image hosting only works through a browser session, so an agent that just captured a before/after has nowhere to put it.

uploads gives agents that missing step, and it works while the branch is still in progress. An agent runs uploads put ./after.png the moment a change is visible; on a branch that stages the file automatically — no PR required, no flag to remember. Capture at every milestone and there is nothing to reassemble at the end: when the pull request opens, everything staged is promoted into one tidy comment that updates automatically on each revision.

Keys are hash-free, so re-uploading the same filename overwrites in place and the URL never changes — every embed of it updates at once. Workspaces keep tenants (and their budgets and key policies) apart.

This repo is the source of the canonical deployment at uploads.sh: the API worker, auth worker, MCP server, the Astro web app, and the @buildinternet/uploads CLI (published to npm from packages/uploads).

What it looks like

One comment per PR, rewritten in place on every sync. Files tagged --state before and --state after pair into a side-by-side table; anything else lands below it.

The managed attachments comment on a pull request, with a before/after pair rendered side by side under Before and After headings

The real comment on #436.

Pairing is by --meta path=… when several pairs share a comment (one before and one after per path), and falls back to filenames that differ only by a before/after token — hero-before.webp with hero-after.webp.

Everything you attach also lands in your workspace, grouped by where it came from — pages by path, projects by repo or app — and browsable from one place.

The screenshots view in a workspace, with uploads grouped into collapsible sections by project and path

The screenshots view groups uploads by project and path.

Open any file for a share page: copy-ready embeds (Markdown, HTML, and more), the raw URL, and a delete button.

A file share page showing the media preview, a Copy-as embed menu, file details, and a Delete file action

Each file's share page — copy-ready embeds, details, and delete.

Use it

Install the CLI and sign in once:

npm install --global @buildinternet/uploads
uploads login

Then capture as you work. On a branch, a bare put stages the file against that branch — no PR needed yet, and no flag to remember:

uploads put ./before.png --state before
uploads put ./after.png --state after
uploads staged                 # what's queued, and whether it will auto-attach

Open the PR however you normally would (gh pr create, the GitHub UI) and the staged files promote themselves into one managed attachments comment — instantly if the GitHub App is installed, otherwise on your next uploads attach (or uploads attach --promote).

Already have a PR or issue open? Target it directly, no staging step:

uploads attach ./before.png ./after.png

attach detects the repository and current PR through gh, uploads all files, and creates or updates that same one comment. Both commands run under npx @buildinternet/uploads … without a global install.

Sign in with GitHub or a magic link, then create your own workspace or accept an invite into one — see enrollment. Hosted files are public URLs — private-repo attachments get non-guessable links (how that works), but anyone holding a URL can view the file. Do not upload secrets or sensitive UI.

Teach your agent the loop. uploads install wires in the agent skills and the MCP server, so future sessions capture at each visual milestone on their own instead of being asked. The skills also install standalone, into any agent runtime, without checking anything out:

npx skills add buildinternet/uploads

That installs three skills: github-screenshots (visuals → PRs/issues), uploads-cli (full CLI reference), and annotate-screenshots (callouts and redaction on a capture).

Point at what changed before you attach — bake boxes, arrows, labels, or a solid redaction into the image:

uploads screenshot http://localhost:4321/settings --via local --annotate ./callouts.json
uploads annotate ./shot.png --spec ./callouts.json --out ./shot.marked.png

Full CLI usage — key conventions, stable PR/issue attachments, annotations, managed comments, and public galleries — lives in docs/cli.md. REST routes are in docs/api.md.

What's in this repo

Path What
apps/ The deployables: the REST API worker (api.uploads.sh), the auth worker, the remote MCP server, and the Astro site at uploads.sh
packages/ Shared code — most notably @buildinternet/uploads (the CLI, published to npm) and @uploads/storage (the files-sdk adapter factory all storage goes through)
skills/ The three agent skills that ship to users
hooks/, plugins/, .mcp.json Agent-runtime wiring: the shared pre-PR screenshot hook and the Claude / Codex plugin manifests

Each worker and the web app deploy separately. All storage access goes through createStorage() in packages/storage — adding a provider is one new case plus peer deps, no API changes.

Docs

Product docs — install, the staged loop, the GitHub App, limits — live at https://uploads.sh/docs. The docs in this repo are the companion: CLI and API reference, contributor setup, and operator material, all mapped from docs/README.md.

How to set up, test, and open a pull request: CONTRIBUTING.md. Where the project is headed: VISION.md. Agent working conventions live in AGENTS.md, and agents that land on this repo should start at llms.txt. The product site serves https://uploads.sh/llms.txt and https://uploads.sh/llms-full.txt.

Local development

Prerequisites: Node ≥24 and pnpm ≥11 (corepack enable). No Cloudflare account needed for the core local loop — wrangler dev simulates R2, KV, and D1 on disk:

pnpm bootstrap        # one-command setup: tooling, deps, env vars, local D1, default workspace
pnpm dev              # API on :8787 (local R2 + KV + D1)

bootstrap is idempotent, and pnpm doctor diagnoses a setup without changing it. The rest of the loop — the authenticated dev stack, the check and test gates, and how to open a pull request — is in CONTRIBUTING.md.

License

Apache 2.0.

About

Lightweight upload tool for coding agents to add screenshots to pull requests. Cloud and self-host options.

Topics

Resources

Contributing

Stars

16 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Contributors

Languages