Communitygithub.com

shenmituzi/img-share

DSH skill: share browser screenshots / local images in chat (thumbnail + fullscreen, phone-visible)

img-share란 무엇인가요?

img-share is a Claude Code agent skill that dSH skill: share browser screenshots / local images in chat (thumbnail + fullscreen, phone-visible).

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add shenmituzi/img-share

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

img-share Skill

浏览器截图本地图片变成聊天框内的可点大图(缩略图+点击看原图),并且手机/其他设备也能访问。跨平台(Linux/macOS/WSL/Windows 原生均可用)。

whenToUse(何时触发)

  • 用户要"打开某个网站/页面截图给我";
  • 把某张图贴到聊天框,且希望"手机也能看、能点开放大看细节";
  • 想把工作区图片做成可点大图的聊天内嵌图

依赖

依赖用途获取
web-access skill截图(CDP 驱动浏览器)需装:https://github.com/eze-is/web-access
python3/python编排器(serve.py)系统自带
cloudflared兜底公网隧道mac: brew install cloudflared;win: winget install Cloudflare.cloudflared;linux: 见其官方 README;或设 CLOUDFLARED=/路径
ffmpeg(可选)多图拼网格系统安装(scripts/montage.sh 用)

执行步骤

  1. 宿主可达性判定(必选,最先做) —— 决定图片 URL 的基址,以及是否需要另开公网隧道。图片地址必须跟随宿主地址,不要为了"能跑通"就擅自另开一条与宿主不同源的隧道:

    判定结论(行动)
    宿主已被隧道化/公网可达(用户手机正是通过该地址访问本会话),且宿主暴露了静态图片路径(如 /img/*图片放进宿主静态目录,内嵌用 宿主公网地址不开新隧道
    宿主公网可达,但未暴露静态图片路径不静默兜底:先告诉用户"需给宿主配置静态图片映射";仅当用户知情同意后才走"显式独立隧道兜底"
    宿主仅 localhost(如 DSH_WEB_URL=http://127.0.0.1:*,未开公网)图片只有本机/局域网地址,手机本来也到不了本会话 —— 先提示用户把 DSH 开成公网,或经用户同意走显式兜底;禁止把 localhost/127.0.0.1 地址内嵌并宣称手机可看
    探测不到 / 不确定不猜测,先问用户:"你手机访问本会话用的是哪个地址(公网域名还是 localhost)?" 再按上表执行

    探测方式:读环境变量(DSH_WEB_URLDSH_PUBLIC_BASEDSH_IMG_BASE 等)、查宿主静态路由配置;取不到即视为"宿主未提供",按上表走"问用户/提示",不得静默降级为另开隧道

    宿主契约(前瞻约定,当前 DSH 宿主尚未提供):宿主若暴露 DSH_PUBLIC_BASE / DSH_IMG_BASE 或等价的静态路径声明,agent 必须优先把图片挂到宿主域名下;未提供时不要假设存在。

  2. 截图(如需):用 web-access skill,/screenshot 渲染页面成 PNG。

    • 若 CDP/Chromium 在受限环境跑不起来(禁联网/进程崩溃),降级到云端截图:用 thum.io / mshots / microlink 等,带 ?wait=N&width=W,返回后校验"非白像素占比>阈值、色簇数>N",不是空白才可用。
  3. 存图:放到工作区(如 img/x.png,文件名用 ASCII/无空格)。

  4. 分享(按第 0 步结论,二选一):

    • 宿主路径(第 0 步判定为可复用宿主时):把图片放到宿主暴露的静态目录,内嵌 https://<宿主域名>/img/x.png不要开独立隧道
    • 显式兜底(第 0 步判定为需兜底且用户同意时):只分享这一个文件,不开整个目录;起图库[仅回环]+公网隧道,端到端校验,输出 PUBLIC_BASE:
      bash <skill>/scripts/setup.sh <img>/x.png        # Unix/WSL
      python <skill>/scripts/serve.py --share <img>/x.png   # Windows 原生
      
  5. 回复里内嵌(缩略图=原图 URL,点击开原图全屏):

    [![描述](https://<基址>/x.png)](https://<基址>/x.png)
    

    基址必须是第 0 步判定的结果(宿主公网地址,或用户知情同意的显式隧道地址);禁止 embed localhost/127.0.0.1 并声称手机可看。告知用户:聊天框显缩略图,点击开原图;手机用同一公网地址也可访问(已验证 DSH 能渲染公网 markdown 图片)。

  6. 分享完毕→撤隧道(显式兜底场景,避免长期公开):

    bash <skill>/scripts/teardown.sh                  # 停图库+隧道+清理
    

失败处理

  • 宿主可达性无法判定:不猜、不静默另开隧道;先问用户手机访问本会话所用的地址(见第 0 步)。
  • 宿主公网但无静态图片路径:提示用户配置静态映射,或征得同意后走显式兜底,并说明该隧道与宿主不同源。
  • 缺依赖:serve.py 报"缺 cloudflared/python",按提示装或设 CLOUDFLARED;截图缺 web-access 则走云端截图(见上)或让用户传图。
  • 端口被占:serve.py 自动选空闲端口。
  • 隧道域名取不到(网络慢/断连 Cloudflare):serve.py 轮询重试;仍失败则告知"网络无法建隧道",回退为仅本机/局域网(给本机地址,并说明手机场景需先让宿主/服务公网可达)。
  • 端到端校验失败:serve.py 会 curl 真实文件名校验(200 才成功),失败即撤,避免"看似 live 实则 404"。
  • 域名漂移:快捷隧道重启换域名,旧内嵌 URL 失效;宿主路径无此问题;兜底场景长期稳定用命名隧道/固定域名

环境自检(Agent 先做)

开始前先探测:能否出网(curl 一个公网地址)、能否spawn 浏览器进程(CDP)、宿主是否为公网可达(见第 0 步)。出网/CDP 都不行 → 走云端截图 + 提示需要更高权限,不要直接给用户一个"看起来能但实际裂"的图。

安全(默认动作,非提醒)

  • 只分享指定文件:serve.py 把要分享的文件拷进随机命名子目录再起服务,绝不开整个 img/ 目录(否则隧道 URL 能列出/下载该目录所有文件);宿主静态目录同理只放要分享的文件。
  • 图库仅绑定 127.0.0.1(局域网不能直连);公网隧道 URL 无鉴权——分享完立即 teardown
  • 想更严:给 URL 加随机 token / 用短时隧道;别放敏感图
  • 别把所有图都放公网:只让"本次要分享的那一张/几张"出现在可公开访问的目录/隧道中。

宿主隧道优先(判定见执行步骤第 0 步)

  • 图地址跟随宿主地址:宿主已被隧道化/公网化时,图片应挂在宿主同一域名(如静态 /img/* 路径)下——用户手机上打开会话即能加载,无需、也不应另开一条与宿主不同源的临时隧道。
  • 若宿主通过 dsh-trust-proxy 等暴露了 /img/ 静态规则,图片 URL 形如 https://<DSH域名>/img/x.png,跨设备、免多开隧道。
  • serve.py 的独立 cloudflared 隧道只是可移植兜底(任何机器都能跑):仅在第 0 步判定"宿主不可公网复用"且用户知情同意后使用,并明确告知其局限(与宿主不同源、快捷隧道重启即换域名)。

边界

  • 进程要常驻/可撤:serve.py 记录 PID 供 teardown;DSH 会话里服务需跨会话(可用托管后台 + teardown 明确清理)。
  • 文件名:用 ASCII、无空格;脚本对文件存在做校验,中文/空格由 URL 编码处理,但建议避免。
  • 工作区不同:不同会话工作区不同,按该会话路径分享;serve.py 用系统临时目录,不依赖工作区。

관련 스킬