关于 github-screenshots
github-screenshots 是一项技能,用于在 GitHub 拉取请求和议题中捕获、托管并嵌入截图或其他文件。它说明何时选择 GitHub 原生附件或 uploads.sh,并介绍 CLI 与托管 MCP 工作流。
主要功能
- 01捕获并托管截图
- 02在拉取请求和议题中嵌入公开链接
- 03在拉取请求创建前暂存视觉素材
- 04保留路由和状态元数据
- 05选择 GitHub 附件或 uploads.sh
适用场景
- 01在拉取请求中添加前后对比截图
- 02分享 GitHub 附件不支持的报告或文件
- 03开发过程中暂存视觉进展
- 04发布可在 GitHub 外访问的链接
MCP 相关
该技能介绍如何使用 https://agents.uploads.sh/mcp 托管 MCP 上传已提供的文件内容或获取公开 URL,并返回可嵌入的链接。若有 Shell 但没有 uploads 二进制文件,也可通过签发上传 URL 完成上传。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ buildinternet/ uploads --skill github-screenshots安装后在 Claude Code 中输入/github-screenshots确认已加载。
详细介绍
原文在翻译后有更新,译文可能不是最新。
在 GitHub PR 和 issue 中使用截图和录屏
为什么需要它
GitHub 原生图片托管服务(github.com/user-attachments/…)可从浏览器访问;自 GitHub CLI 2.99(2026 年 9 月)起,也可通过 gh issue|pr create|edit|comment --attach <file> 访问。目前仍没有公开的 REST 端点(CLI 使用的是未公开的上传主机),上传需要推送权限,而且托管的文件仅限 GitHub 内访问。使用 gh … --body-file 编写 PR/issue 正文时,任何其他图片 URL 都必须已指向公开托管的位置。uploads CLI 和托管的 MCP https://agents.uploads.sh/mcp 都会将文件托管在 uploads.sh 上,并返回稳定的公开 URL 以及可直接粘贴的 Markdown。
何时只用 gh --attach 就够了
当以下条件全部满足时,使用普通的 gh pr comment --attach ./shot.png(或 create/edit):
gh --version为 2.99 或更高版本,并且你拥有仓库的推送权限。- PR 或 issue 已存在,或者你会在同一条命令中创建它。
- 文件是小于 10 MB 的图片或视频(付费方案支持最大 100 MB 的视频)。
gh --attach仅接受媒体文件。 - 没有人需要在 GitHub 之外访问链接。
user-attachmentsURL 无法在 Slack、文档或其他工具中显示,其他 Agent 也无法获取这些文件。
当符合以下任一条件时,请改用 uploads.sh:
- 文件不是媒体文件:例如 Lighthouse 或测试报告、日志、JSON、PDF 或 zip。
gh --attach不接受这些文件;uploads put可以,且托管评论会提供链接。 - PR 尚不存在。在分支上使用
uploads put暂存;PR 创建后会显示附件评论。 - 截图会重新拍摄。文件名和 URL 保持不变,托管评论会原位更新,而不是不断堆积。
- 截图需要元数据(
--meta)、后续检索(uploads find)或跨项目查看 Screenshots 视图。 - URL 必须能在 GitHub 之外使用。
- 你使用的是没有 shell 的托管 MCP、缺少推送权限,或者仓库位于 GitHub Enterprise Server 上。
不要在同一个 PR 中混用两者:请选择一种,以保持评论历史清晰。通过 gh 附加的媒体仍会被索引:GitHub App 会将 PR 和 issue 正文中的附件导入工作区。同一 webhook 也会导入正文中公开的 Cursor cursor.com/artifacts/c/art-* 重写 URL。若要手动镜像现有的 user-attachments 图片或 art-* URL,请使用 uploads ingest。
选择哪种方式
选择一种传输方式并坚持使用。本技能负责工作流。uploads-cli 技能负责标志和 MCP 工具契约。
| 你具备的条件 | 使用方式 |
|---|---|
| 没有 shell(ChatGPT,或任何没有代码检出的宿主) | 使用托管 MCP put,并提供(contentBase64 + filename,或 contentUrl)+ repo +(pr 或 branch)。当 URL 路径包含末尾文件名时,使用 contentUrl 可不提供文件名。嵌入返回的 markdown / embedUrl。绝不要暗示你可以运行 uploads attach ./shot.png。 |
有代码检出和 uploads 二进制文件 | 使用下方的 CLI 示例。Git 可以填入 repo / branch。 |
localhost 页面或选择器批注 | 仅使用 CLI(uploads screenshot --via local)。远程渲染无法访问你的计算机。 |
| 既没有 MCP,也没有 CLI | 停止并说明这一点。不要把 npm install -g 当作 ChatGPT 的使用方式。 |
托管 MCP 上没有 attach 工具,也没有 git 默认值。使用
put + branch + repo 暂存。PR 创建后,使用 repo + pr +
branch 调用 promote,或使用 pr + repo 调用 put(也可选提供 branch 以进行提升)。
托管评论只能由该服务上的机器人发布。
步骤 1 — 捕获视觉内容
如果视觉内容已在上下文中(例如 ChatGPT 附件或宿主已持有的文件),请跳过此步骤。直接前往托管 MCP 的 put。
优先使用 uploads screenshot <url|file.html>——它可以一步完成捕获和托管(驱动本地 Chrome,或回退到服务端渲染),因此无需单独调用托管命令。它支持 --viewport WxH@Nx、--wait、--selector、--full-page 和 --out <file>(同时保存 PNG)。
要捕获你自己的开发服务器?无需手动操作 DOM:
- 已知框架的开发工具栏(Astro/Next/Nuxt/Vite)会自动隐藏——使用
--no-hide-dev-tools可关闭此功能。 --reduced-motion会使动画静止。--hide <selector>可隐藏其他覆盖层(可重复使用)。--eval <js>/--init-script <file>(本地后端)是用于关闭横幅或冻结特定动画的备用方案。
要捕获 React/Next(或其他需要水合的)应用中已点击/选中的状态?在 --eval 中调用合成的 el.click() 时,框架尚未完成水合——元素存在于 SSR HTML 中,但尚未附加处理程序,因此调用会悄无声息地失效。使用 --wait-for <js>(本地后端)等待应用自身的“可交互”信号。该参数会轮询表达式,直到其结果为真,然后才运行 --eval:
uploads screenshot http://localhost:3000 --via local \
--wait-for 'document.querySelector("[data-hydrated]")' \
--eval 'document.querySelector(".tab-settings").click()' --out settings.png
uploads screenshot http://localhost:4321 --viewport 1520x960@1x --out home.png --reduced-motion
uploads screenshot https://uploads.sh --selector main --dark
--out 还会在 PNG 旁生成一个 <file>.uploads.json 辅助文件——这是供后续 put/attach 使用的工作文件,用于恢复元数据,不应提交。因此,请将 *.uploads.json 加入 .gitignore,或在完成附加后将其删除。
只有当 uploads screenshot 无法访问目标内容时(例如流程需要先进行身份验证或交互),才使用你的测试工具所提供的浏览器工具、Playwright 或现有文件。GIF 和视频:使用任意工具捕获后原样上传——优化器只会重写静态图像(PNG/JPEG → WebP)。
步骤 2 — 托管并嵌入
分为两个层级,根据是否已有 PR 选择:
- 简单 — 已有 PR/issue。 使用
uploads put shot.png --pr 123(或使用uploads attach shot.png,它会从当前分支推断 PR)——一次调用,即可获得每个 PR 稳定的键、立即返回嵌入 URL,并且托管评论会顺带收集该 PR 的媒体文件。 - 高级 — PR 创建前暂存,尚无可关联的目标。 在分支上使用
uploads put shot.png(见下文)——暂时无需 PR/issue;PR 创建后会自动推广并发表评论,但仅限已绑定到工作区的仓库(见下方注意事项)。除非你有意在较长的分支上逐步构建暂存集,否则 PR 创建后请使用简单模式。
默认流程:边做边暂存,从第一个视觉里程碑开始。 不要等 PR 创建后再操作——在分支上执行任务时,只要有值得捕获的内容,就立即附加。
以下两个命令无需额外标志即可自动暂存:
- 不带参数的
uploads put:当你位于 Git 仓库的非默认分支上,且未指定--pr/--issue/--key/--ref/--prefix时使用。它会暂存到与attach --branch相同的分支键路径下。 - 不带
--pr/--issue/--branch目标的uploads screenshot。直接从 URL 捕获时,所有派生信息——路径、URL、环境、视口以及--state——都会保留,并在 PR 创建后传递到 PR。
仅当你需要其附加功能时,才显式使用 attach --branch:例如一次上传多个文件并共用标志,或顺带触发推广/评论同步。
暂存键中包含分支名称。分支重命名后,下次你在该分支上运行任何 uploads 暂存或推广命令时,系统都会自动更新键。如果 PR 在此之前创建,请使用 uploads attach --pr <n> --from-branch <old-branch-name> 找回遗留文件(见 uploads-cli)。
uploads screenshot http://localhost:4321/settings --out step1-before.png --state before
uploads screenshot http://localhost:4321/settings --out step2-after.png --state after
# or, capturing an existing local file instead of a live URL:
uploads put ./step1-before.png --meta path=/settings --state before
# or, explicitly, e.g. to upload several at once:
uploads attach ./step1-before.png ./step2-after.png --branch --state after
这会上传到按分支键控的稳定路径(无需指定 PR/issue 目标,也不会立即评论——PR 尚不存在,还无内容可评论)。工作时,每到一个有意义的视觉里程碑都这样做;不要等到最后再一次性批量上传。在默认分支上(或不在 git 仓库中,或使用 --no-git 时),put/screenshot 会回退到常规的按日期归档布局——也可以通过 --key/--ref/--prefix/--destination 退出此行为。
暂存内容只会自动晋升到已绑定的仓库——不要想当然地承诺。 PR 打开时自动晋升(通过 webhook 或下文所述的 CLI 触发)要求仓库已绑定到工作区。绑定有两种方式:
- 隐式绑定:此前针对该仓库成功调用过 attach/comment/promote。
- 显式绑定:通过
uploads github link。
从未绑定过、且只使用 --branch 暂存内容的仓库,在 PR 打开时不会报错,也不会评论——操作会静默无效。因此,如果无法确认仓库已绑定(uploads github link --status),就不要告诉用户截图会“自动出现”。无论此前是否绑定,都有效的备用方案是:PR 创建后,运行 uploads attach --promote(或针对该 PR 运行任意一次定向的 uploads attach),以显式晋升内容并发布评论。
**养成习惯:每次都传入 --state before/--state after 和 --meta path=/route——两者都要传。**它们是价值最高的两个可查询标签,也是工具之后无法补回的两项信息:
--state的 before/after 是大多数 PR 截图的核心信息,无法从图像中推断。path同样容易忘记,不过uploads screenshot例外,它会从捕获的 URL 推导路径。对现有文件执行put/attach时,没有 URL 可供推导。
现在只多传一个标志,就能让 uploads find state=after 或 uploads find path=/settings 在几个月后仍可用,那时文件名对任何人都毫无意义。
**对于 URL 相同的 before/after 截图,直接使用 uploads screenshot 最简单。**其对象名称由捕获的 URL 推导而来,--state 会并入名称——localhost-docs-mcp.webp 会变成 -before.webp/-after.webp。因此,对同一 URL 使用不同状态捕获两次,会生成两个不同对象,而不是让其中一个覆盖另一个。需要指定对象名称时,传入显式的 --key。对现有文件执行 put 时,没有 URL 可供推导文件名主体,因此应使用不同文件名或 --key 区分 before/after:
uploads screenshot https://app.example/settings --pr 123 --state before
uploads screenshot https://app.example/settings --pr 123 --state after
uploads put ./after.png --pr 123 --meta path=/settings --state after
(--state 也接受 empty、error 和 loading。)如果图像上传时没有 path 元数据,attach/put --pr/put --issue 会在 stderr 上打印 tip: add --meta path=/route so this shot is findable by page(并在 JSON 中提供 hint 字段)——不要忽略此提示。在 screenshot 中,视口信息会自动推导。完整的规范词汇表请参阅 uploads-cli 技能说明。
**PR 评论会自动生成——无需你处理这一步。**PR 打开后(无论通过 gh pr create 还是 GitHub UI),每个按分支暂存的文件都会晋升到该 PR 的附件中,并自动创建托管评论。即使描述中完全没提到的文件,也会显示在评论里。评论通过顶部隐藏的 HTML 注释标识:
``。Bot 发布的评论来自
uploads-sh[bot];本地 gh 回退方案使用相同的标记。
- 如果仓库已安装 uploads-sh GitHub App,PR 打开、重新打开或收到新提交时,webhook 会立即完成此操作——完全不需要调用 CLI。
- 如果没有安装 App,你接下来针对该 PR 运行的
uploads attach会顺带触发相同的晋升和评论更新。如果 PR 打开后没有新内容要添加,运行uploads attach --promote(不带文件参数),即可显式晋升并更新评论——即使没有暂存内容,也会以0退出。单次调用中使用--no-promote可跳过自动晋升。 “PR 已存在”只是同一条命令的简单情况——仍然使用uploads attach,只是将目标设为 PR/Issue 编号,而不是分支;由于已有内容可供评论,评论会立即更新:
uploads attach ./before.png ./after.png
uploads attach ./flow.gif --issue 45 --repo myorg/myapp
uploads attach ./shot.png --no-comment # stable URLs only, no comment
如果要在 PR/Issue 正文中硬编码 URL(重新上传会覆盖原位置,URL 永远不变),可以将图片放进描述中——适合在说明文字中展示相关视觉内容(例如“外观”中的前后对比)。但这不是必须的。等 PR 创建后再使用
--pr,这样正文从一开始就会使用稳定的 pull/<n>/ 键。不要先把暂存到分支的 URL 粘贴到描述中,之后再改成 pull/<n>/ 来“修正”。
uploads put ./after.png --pr 123 --alt "Dashboard after" --width 700
如果需要可在任何地方分享的持久公开链接(Slack、文档、同事):
uploads put ./demo.gif --format url
嵌入图片时,请使用返回的 Markdown(或 embedUrl)——它使用无缓存的主机,因此覆盖后会同步更新。不要手动拼接存储 URL。
变更动态(实时页面,而非图库)
动态页面会按时间倒序展示已标记 GitHub 仓库的最新截图,也可以限定为某个拉取请求。这是同一款产品;--pr 只是额外的筛选条件。它不是精选图库(图库仍通过 uploads gallery create 创建)。
- 仓库动态——分享“这个仓库最近合入了什么”。
- PR 动态——为审查者或 Slack 分享“此拉取请求的所有内容”。
uploads feed create owner/repo
uploads feed create --repo owner/repo
uploads feed create --repo owner/repo --pr 123
uploads feed create --github owner/repo#123
MCP:使用 feed_create 并指定 repo、repo + pr,或仅指定 github。标志说明请参阅
uploads-cli。再次创建相同范围的动态时,会返回现有 URL。
托管的 PR 评论以 N files · View all on uploads.sh → 开头,并链接到该 PR 的动态页面(网页界面称之为“实时链接”)。点击图片会打开
/c/<id>/<item>(可在该 PR 的文件中查看较新/较旧的内容),而不是独立的
/f/ 页面。下次同步评论时,如果动态页面尚不存在,就会自动创建;无论是通过机器人还是本地 gh 后备方案,都是如此。<img src> 仍使用嵌入 URL。
评论短暂消失了?别急着重新发布。 如果已安装 App 且订阅了
issue_comment 事件,那么被删除或编辑掉的托管评论会在下次收到 Webhook 时自动恢复——无需再次运行
comment/attach 来恢复它。
删错截图了? 请对相应对象运行 delete。删除
gh/ 附件时,会尽可能刷新托管评论;否则会提示你重新运行 comment(或托管的 comment 工具)。暂存了错误的分支?运行 uploads unstage --branch <name> 可保留文件并将其从晋升中移除。最后一个附件被删除后,评论会原地改写为空白的中性状态——评论仍会保留在 PR 上(之后上传内容时会重新填充),而不会留下指向已删除文件的过期条目。
机器人评论完全没有显示? 托管评论需要绑定仓库和工作区(通常会在首次调用 comment/promote 时自动创建,或通过安装 GitHub App 创建)。如果预期的评论没有出现,请先检查绑定:
uploads github link --status
此操作只读,会显示当前绑定(或说明仓库未绑定),不会认领任何内容。如果 CLI 报告 not_authorized,则说明该仓库已绑定到_另一个_工作区;此时不会改用你自己的 gh 身份验证来发布评论。解决方法是从所属工作区运行 uploads github unlink --repo owner/name,或请操作员重新分配绑定;切换到当前拥有该仓库的工作区也可以。
精选内容,不要一股脑全倒进去。 评论最多内嵌 16 张图片;超出的图片会折叠到 <details> 溢出列表中。请为截图取有意义的名称并谨慎挑选(例如 before.png/after.png,而不是 capture-1 到 capture-40),不要把长时间会话中的每张随手截图都附上——精心挑选的几个关键节点,比直接倒入整个文件夹更易于阅读。
第 3 步——嵌入得当
-
始终提供有意义的替代文本(
--alt)。 -
对较大的截图使用
--width限制宽度(会生成带尺寸的<img>)。 -
前后对比并排展示效果最佳:
| Before | After | | ------------------------------------ | ----------------------------------- | | <img width="380" src="…/before.png"> | <img width="380" src="…/after.png"> | -
**动态内容:**GitHub 只会在行内播放原生
user-attachments视频。uploads put clip.mp4 --pr N会在托管评论中放入一张海报图(静态画面加播放按钮)。对于 PR 正文,请使用 GIF,或使用链接到视频的静态图片。 -
将正文写入文件,并使用
gh pr edit --body-file/gh issue comment --body-file,不要使用内联 HEREDOC。
设置与升级处理
- 没有 shell?请使用托管 MCP。不要安装 CLI。
- 机器上有 shell,但缺少 CLI?运行
npm install --global @buildinternet/uploads - CLI 尚未通过身份验证?运行
uploads login(一次性操作,会打开浏览器),然后运行uploads doctor进行验证。托管 MCP 会在首次调用工具时使用 OAuth。 - 其他更深入的内容——标志、密钥布局、MCP 工具契约、元数据与搜索、图库、配置默认值、输出格式、退出代码——请参阅 uploads-cli 技能和
uploads <command> --help。
注意事项
- 上传内容公开且实际上永久保留,除非将其删除。GitHub 仓库的可见性不能用作访问控制,而且
gh/<owner>/<repo>/pull/<num>/…密钥可预测。切勿上传机密、令牌或客户个人身份信息(PII)——请先裁剪或遮盖。 - **文件被暂扣不代表上传失败。**如果托管评论显示
🔒 N files are held for review,说明 uploads.sh 认为某张截图中包含机密或个人数据;该文件及其 URL 不会显示在评论中,直到审核通过。运行uploads approve --pr <n>查看具体文件及原因。检查该文件:如果其中包含真实凭据,请告知用户轮换凭据,然后遮盖并重新上传。否则运行uploads approve --pr <n> --all。未经检查,不要代替用户批准。 - **私有仓库会自动获得无法猜测的 URL。**当 uploads GitHub App 检测到目标仓库是私有仓库时,附件密钥会改为
gh/private/<id>/…,无需指定标志。暂存文件的密钥为gh/private/<id>/branch/<filename>:该 id 对应一个分支,因此密钥中不会包含分支名称。uploads staged --branch只会列出该 id。已添加到拉取请求中的文件不会列出。该 id 持久有效,但不受访问控制:任何获得 URL 的人都能读取文件,直到你轮换它(uploads github rotate-prefix)。完整说明请参阅 docs/private-attachments.md。
需要在截图中标注某个内容?
方框、箭头、标签、自由绘制的笔画和遮盖(适用于截图中捕获到的机密内容,请使用纯色遮盖——模糊的文字可能会被还原)可通过 uploads screenshot --annotate 或 uploads annotate 烘焙到截图中——请参阅 annotate-screenshots 技能,了解规范格式和工作流,然后返回此处添加附件。