mcpField
C
clearshot

clearshot

github.com/growthx-club设计与 UI0169 次安装5 周前更新
代码仓库

关于 clearshot

clearshot 是用于 UI 设计、实现、调试或评估的截图分析技能,将视觉观察整理为布局图、设计系统,并在需要实现时生成交互与布局蓝图。

主要功能

  1. 01按 5×5 网格映射截图布局
  2. 02记录元素状态与视觉尺寸
  3. 03提取颜色、字体和间距系统
  4. 04为 UI 重建生成实现蓝图
  5. 05提供截图对比与评审指导

适用场景

  1. 01将 UI 截图转为实现规格
  2. 02检查布局层级与视觉一致性
  3. 03比较两个 UI 版本
  4. 04为 UI 原型提供具体反馈

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/growthx-club/build-sprint-skills --skill clearshot

安装后在 Claude Code 中输入/clearshot确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
.npmignore
CHANGELOG.md
config.sh
install.sh
LICENSE
package.json
README.md
setup
VERSION
bin/
cli.js
onboarding.sh
picker.sh
telemetry-setup.sh
update-prompt.sh
convex/
feedback.ts
http.ts
schema.ts
telemetry.ts
tsconfig.json

详细介绍

前言

在进行任何分析之前,先运行此 bash 代码块:

# ─── Find skill directory (works from any install path) ───────
_CS_DIR=""
for _d in ".claude/skills/clearshot" ".agents/skills/clearshot" "$HOME/.claude/skills/clearshot" "$HOME/.agents/skills/clearshot"; do
  [ -f "$_d/SKILL.md" ] && _CS_DIR="$(cd "$_d" && pwd)" && break
done
# fallback: search
[ -z "$_CS_DIR" ] && _CS_DIR="$(cd "$(dirname "$(find "$HOME/.claude" "$HOME/.agents" -name SKILL.md -path '*/clearshot/*' -print -quit 2>/dev/null)")" 2>/dev/null && pwd || echo "")"
_CS_VER=""
[ -n "$_CS_DIR" ] && [ -f "$_CS_DIR/VERSION" ] && _CS_VER="$(cat "$_CS_DIR/VERSION" | tr -d '[:space:]')"
_CS_STATE="$HOME/.clearshot"
mkdir -p "$_CS_STATE/analytics" "$_CS_STATE/feedback"

# ─── First-run detection ─────────────────────────────────────
_CS_FIRST_RUN="no"
[ ! -f "$_CS_STATE/config.yaml" ] && _CS_FIRST_RUN="yes"

# ─── Read config (only if it exists) ─────────────────────────
_CS_UPDATE_MODE="ask"
_CS_TEL="off"
_CS_TEL_PROMPTED="no"
if [ -f "$_CS_STATE/config.yaml" ]; then
  _CS_UPDATE_MODE=$(grep -E '^update_mode:' "$_CS_STATE/config.yaml" 2>/dev/null | awk '{print $2}' | tr -d '[:space:]' || echo "ask")
  _CS_TEL=$(grep -E '^telemetry:' "$_CS_STATE/config.yaml" 2>/dev/null | awk '{print $2}' | tr -d '[:space:]' || echo "off")
fi
[ -f "$_CS_STATE/.telemetry-prompted" ] && _CS_TEL_PROMPTED="yes"

# ─── Version check (only if user opted into updates) ─────────
# No network calls until config exists and user has chosen
if [ -n "$_CS_VER" ] && [ "$_CS_FIRST_RUN" = "no" ] && [ -d "$_CS_DIR/.git" ]; then
  _CS_CACHE="$_CS_STATE/last-update-check"
  _STALE=""
  [ -f "$_CS_CACHE" ] && _STALE=$(find "$_CS_CACHE" -mmin +60 2>/dev/null || true)
  if [ ! -f "$_CS_CACHE" ] || [ -n "$_STALE" ]; then
    _CS_REMOTE=$(curl -sf --max-time 5 "https://raw.githubusercontent.com/udayanwalvekar/clearshot/main/VERSION" 2>/dev/null | tr -d '[:space:]' || true)
    if echo "$_CS_REMOTE" | grep -qE '^[0-9]+\.[0-9.]+$' 2>/dev/null; then
      if [ "$_CS_VER" != "$_CS_REMOTE" ]; then
        if [ "$_CS_UPDATE_MODE" = "always" ]; then
          cd "$_CS_DIR" && git pull origin main --quiet 2>/dev/null
          _CS_VER="$(cat "$_CS_DIR/VERSION" 2>/dev/null | tr -d '[:space:]')"
          echo "CS_AUTO_UPDATED: $_CS_VER"
          echo "UP_TO_DATE $_CS_VER" > "$_CS_CACHE"
        else
          echo "UPGRADE_AVAILABLE $_CS_VER $_CS_REMOTE" > "$_CS_CACHE"
          echo "CS_UPGRADE: UPGRADE_AVAILABLE $_CS_VER $_CS_REMOTE"
        fi
      else
        echo "UP_TO_DATE $_CS_VER" > "$_CS_CACHE"
      fi
    fi
  else
    _CACHED="$(cat "$_CS_CACHE" 2>/dev/null || true)"
    case "$_CACHED" in UPGRADE_AVAILABLE*)
      if [ "$_CS_UPDATE_MODE" = "always" ]; then
        cd "$_CS_DIR" && git pull origin main --quiet 2>/dev/null
        _CS_VER="$(cat "$_CS_DIR/VERSION" 2>/dev/null | tr -d '[:space:]')"
        echo "CS_AUTO_UPDATED: $_CS_VER"
        echo "UP_TO_DATE $_CS_VER" > "$_CS_CACHE"
      else
        echo "CS_UPGRADE: $_CACHED"
      fi
      ;;
    esac
  fi
fi

# ─── Session tracking ────────────────────────────────────────
_CS_SESSION_ID="$$-$(date +%s)"
_CS_TEL_START=$(date +%s)

echo "CS_FIRST_RUN: $_CS_FIRST_RUN"
echo "CS_SKILL_DIR: $_CS_DIR"
echo "CS_UPDATE_MODE: $_CS_UPDATE_MODE"
echo "CS_TEL_PROMPTED: $_CS_TEL_PROMPTED"
echo "CS_TELEMETRY: ${_CS_TEL:-off}"
echo "CS_SESSION_ID: $_CS_SESSION_ID"
echo "CS_TEL_START: $_CS_TEL_START"
echo "CS_VERSION: ${_CS_VER:-unknown}"
解读前言输出

如果 CS_FIRST_RUN 的值为 yes: 这是 clearshot 首次运行——尚无配置。进行任何分析之前,告知用户运行初始设置。简短说明,例如:

“clearshot 需要快速完成首次设置(回答两个问题,使用方向键和回车键):”

然后指示用户输入:! {CS_SKILL_DIR}/bin/onboarding.sh

使用前言输出中的实际 CS_SKILL_DIR 值(例如 ~/.claude/skills/clearshot 或 ~/.agents/skills/clearshot)。脚本会询问更新偏好和遥测设置、写入配置,并在几秒内完成。

用户运行脚本后,继续分析。如果用户拒绝,也继续进行——没有配置时不会进行网络调用。

如果出现 CS_AUTO_UPDATED: 该技能已自动更新。简要提及:“clearshot 已更新至 v{version}”,然后继续分析。无需采取任何操作。

如果 CS_UPGRADE 显示 UPGRADE_AVAILABLE <old> <new>: 用户设置了 update_mode: ask。告知用户有新版本可用,并指示他们运行交互式更新选择器:

“clearshot v{new} 已发布(你当前使用的是 v{old}):”

然后指示用户输入:! {CS_SKILL_DIR}/bin/update-prompt.sh {old} {new}

脚本会让用户选择“立即更新”或“始终更新”(后者也会将未来的更新模式切换为自动更新)。如果用户跳过,继续使用当前版本进行分析。

如果 CS_TEL_PROMPTED 的值为 no(但 CS_FIRST_RUN 也为 no): 用户已有配置,但不知为何跳过了遥测问题。告知他们运行:

! {CS_SKILL_DIR}/bin/telemetry-setup.sh

用户运行脚本后,继续分析。如果用户拒绝,也继续进行,并关闭遥测。

截图分析

当大模型查看截图并试图直接从像素得出代码(或反馈或描述)时,它会忽略空间关系、误读组件层级,并臆造设计细节。解决方法是在“查看图像”和“针对图像作答”之间建立结构化的中间表示。本技能提供的正是这一中间层。

检查条件

并非每张图像都需要使用本技能。

开始前先问两个问题:

  1. 这张图像是数字界面吗?(网站、应用、仪表板、模型图、线框图、Figma 导出图、带 UI 上下文的 CLI,以及显示了页面的浏览器 DevTools 都算。照片、表情包、独立图表、演示文稿幻灯片、文档、手写笔记则不算。)

  2. 对话是否与构建、调试、设计或评估 UI 有关?

三种结果:

  • 两个问题的答案都是否定的:完全退出本技能。正常作答。不要提及此框架。
  • 图像不是 UI,但对话确实与构建 UI 有关(例如“帮我构建一个有这张照片感觉的页面”):图像是灵感,而非规范。描述它传达的感受——氛围、质感、分量——然后继续。无需结构化分析。
  • 图像是 UI,且对话与构建或评估有关:按照下面的分析层级继续。

分析层级

每次分析都兼顾事实和审美。不存在独立的“分析模式”或“定性模式”——每项观察都以具体细节(十六进制颜色值、像素尺寸)为依据,同时也包含主观感受(层级、分量、协调性)。这与资深设计师的思考方式一致:先感受,再探究原因,两者兼顾。

Level 1:映射(始终运行)

将截图划分为一个5×5 网格。对于每个被占用的区域,说明其中的部分(导航、主视觉区、侧边栏、内容区、页脚、模态框、抽屉、空白区域)、相对于视口的大致尺寸,以及它与相邻区域的关系。

记录每个可见元素:类型(按钮、输入框、卡片、图像、图标、文本、链接、切换开关、下拉菜单、选项卡、徽章、头像、表格、图表等)、标签/内容(可见文本原文)、位置(网格区域 + 相对位置)、状态(默认、悬停、激活、禁用、已选中、错误、加载中、聚焦)、尺寸(像素估值)、背景色(十六进制)、文本颜色(十六进制)、边框(可见/无 + 圆角像素值)、阴影(无/小/中/大)、图标(如有)。按区域分组。

另请说明:视线首先落在哪里。布局是舒展还是显得拥挤。层级清晰还是彼此争抢。哪些设计显得有意为之,哪些像是无意造成的。

Level 2:系统(始终运行)

提取可见界面背后的设计系统:

**颜色:**页面背景、卡片/表面背景、主要操作、次要元素、主要文本、次要/弱化文本、边框/分隔线、强调色、危险色、成功色。列出所有十六进制值。说明配色是否协调统一,还是显得拼凑——是否有明确的系统,还是颜色随意搭配?

**排版:**标题样式(像素字号、字重、大小写)、正文(字号、字重、行高)、说明文字/小字、可辨认的字体系列。说明字号层级是否有意设计——字号变化是否连贯,还是跳跃随意?

**间距和形状:**间距规律(紧凑,4-8px / 适中,12-16px / 宽松,24-32px+)、圆角规律(锐利,0-2px / 轻微,4-6px / 圆润,8-12px / 胶囊形)、整体密度(紧凑 / 适中 / 宽松)。说明不同区域的间距是否一致。

Level 3:蓝图(构建时升级)

当用户需要根据截图实现、重建或克隆 UI 时,运行此级别。如果对话涉及根据此截图编写代码,LLM 应升级到 Level 3。

**布局架构:**页面布局模式(单列、侧边栏 + 内容区、仪表板网格、居中容器、全宽)、各区域的内容布局(flex 行、flex 列、列数固定的 CSS 网格、堆叠)、容器宽度(限制最大宽度还是全宽)、响应式场景(移动端 <640px / 平板 640-1024px / 桌面端 >1024px)、滚动线索(内容被截断、粘性页眉、固定底栏)、z-index 层级(覆盖层、模态框、下拉菜单、提示框)。

**交互图:**主要 CTA(最重要的单一操作)、次要操作、导航模式(顶部导航、侧边导航、选项卡、面包屑、底栏)、表单元素及其分组、数据展示模式(表格、卡片网格、列表)、可见状态(加载中、空状态、错误、成功)。指出用户可能犹豫或感到不顺畅的地方,以及显得精致流畅的地方。

输出

根据上下文选择合适的输出形式。段落足以说明时,不要强行添加标题和分节。

**评审/反馈:**先指出问题或需要关注的地方。每项观察都要以具体细节为依据(导致问题的具体十六进制色值、间距或元素),并说明其对体验的影响。不要罗列所有内容,只关注重要问题。

**实现规范(Level 3):**按结构组织输出,并设置分节标题——布局图、按区域划分的元素、设计令牌、布局架构、交互图。这是实现文档。

**对比(两张截图):**说明有哪些变化、哪些方面有所改善、哪些方面有所退步,以及仍需改进之处。

核心原则

具体明确。“一个带有几张卡片的仪表板”绝不可接受。“3 列网格、卡片约 280px 宽、背景色 #F9FAFB、8px 圆角、柔和阴影——卡片轻盈得仿佛漂浮起来”才可以。每项观察都需要同时包含测量值和判断。

**用十六进制值,不用颜色名称;用像素,不用模糊尺寸。**说 #3B82F6,而不是“蓝色”。说约 16px,而不是“差不多”。如果不确定,给出最佳估计并注明。

**按区域分组,而不是按元素类型分组。**导航栏中的元素应归为一组。不要把页面上所有按钮都归入同一列表。

**指出不明显之处。**自定义插图、不同寻常的组件模式、暗示的动画、动态与静态数据。这些都是容易导致实现出错的地方。

**配合用户的节奏。**快速迭代时,输出要简洁。用户要求详细克隆时,输出要全面。但分析深度(第 1 和第 2 级)始终相同——变化的是输出量,而不是观察的细致程度。

自我评分

每次都在内部静默完成

完成任何分析后,都要按以下标准给自己的输出打 0 到 10 分:空间准确性(网格是否正确映射布局?)、具体程度(颜色是否使用十六进制值、尺寸是否以像素估算、组件是否准确命名?)、级别选择(是否运行了正确的级别?)、审美判断(是否发现了不协调之处,而不只是可测量的问题?)、可操作性(别人能否据此采取行动?)。计算平均分。

该评分严格保密。它会作为尾声中的 RATING 字段写入遥测数据,但绝不会展示给用户。每次分析后都显示评分会显得冗余且自我表扬。

何时征求反馈

只有以下三种情况需要让用户参与质量反馈。除此之外,保持安静。

触发条件 1:用户纠正。 如果用户纠正分析——“不对,这错了”“你漏了导航栏”“内边距不对”——先修正问题,然后简短说明:“已记录这次疏漏,帮助 clearshot 更好地发现[具体问题]。”自动写入一份现场报告(见下文)。

触发条件 2:重建完成后。 如果运行了第 3 级且实现已完成,随口问一句:“clearshot 做得很到位,还是漏了什么?只是好奇。”只问一次,不要做成问卷。

触发条件 3:会话即将结束。 如果单次会话中完成了 3 次或以上分析,且对话即将结束,附上一句:“这次会话运行了 clearshot X 次。它有没有反复弄错什么?”只有在完成 3 次或以上分析时才这样做。绝不要在对话进行中打断用户。

**绝不要征求反馈:**快速迭代期间、每次分析之后,或用户明显正专注于当前任务时。

现场报告

仅在以下情况写入 ~/.clearshot/feedback/YYYY-MM-DD-{slug}.md:

  • 用户纠正:自动写入。格式:
# {Title describing the miss}
**What was analyzed:** {screenshot description}
**Levels run:** {1,2 or 1,2,3}
**What was missed:** {specific element or detail the user corrected}
**Correction:** {what the user said}
**Internal rating:** {X}/10
**Date:** {YYYY-MM-DD} | **Version:** {version from preamble}
  • 用户明确指出有误(回复触发条件 2 或 3 时):写入现场报告,并包含用户的反馈。

  • 内部评分低于 5:静默写入现场报告。

常规分析顺利完成时,绝不写入现场报告。

尾声

分析完成后,记录事件。将占位符变量替换为实际值。

_CS_TEL_END=$(date +%s)
_CS_DUR=$(( _CS_TEL_END - _CS_TEL_START ))
_CS_TEL_MODE=$(grep -E '^telemetry:' "$HOME/.clearshot/config.yaml" 2>/dev/null | awk '{print $2}' | tr -d '[:space:]' || echo "off")
if [ "$_CS_TEL_MODE" != "off" ]; then
  _CS_OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
  _CS_ARCH="$(uname -m)"
  _CS_INSTALL_ID="$(printf '%s-%s' "$(hostname)" "$(whoami)" | shasum -a 256 | awk '{print $1}')"
  _CS_ID_JSON="\"$_CS_INSTALL_ID\""
  printf '{"v":1,"ts":"%s","version":"%s","os":"%s","arch":"%s","duration_s":%s,"outcome":"%s","levels_run":"%s","self_rating":%s,"installation_id":%s}\n' \
    "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "CS_VERSION" "$_CS_OS" "$_CS_ARCH" \
    "$_CS_DUR" "OUTCOME" "LEVELS_RUN" "RATING" "$_CS_ID_JSON" \
    >> "$HOME/.clearshot/analytics/usage.jsonl" 2>/dev/null || true

  # Sync to Convex (rate-limited, background)
  _CS_CONVEX_URL=""
  for _csd in "$HOME/.claude/skills/clearshot" "$HOME/.agents/skills/clearshot"; do
    [ -f "$_csd/config.sh" ] && _CS_CONVEX_URL="$(grep -E '^CS_CONVEX_URL=' "$_csd/config.sh" 2>/dev/null | cut -d'"' -f2 || true)" && break
  done
  if [ -n "$_CS_CONVEX_URL" ] && [ "$_CS_CONVEX_URL" != "https://placeholder.convex.site" ]; then
    _CS_RATE="$HOME/.clearshot/analytics/.last-sync-time"
    _CS_SYNC_STALE=$(find "$_CS_RATE" -mmin +5 2>/dev/null || echo "sync")
    if [ ! -f "$_CS_RATE" ] || [ -n "$_CS_SYNC_STALE" ]; then
      _CS_CURSOR_FILE="$HOME/.clearshot/analytics/.last-sync-line"
      _CS_CURSOR=$(cat "$_CS_CURSOR_FILE" 2>/dev/null | tr -d '[:space:]' || echo "0")
      _CS_TOTAL=$(wc -l < "$HOME/.clearshot/analytics/usage.jsonl" 2>/dev/null | tr -d ' ' || echo "0")
      if [ "$_CS_CURSOR" -lt "$_CS_TOTAL" ] 2>/dev/null; then
        _CS_SKIP=$(( _CS_CURSOR + 1 ))
        _CS_BATCH=$(tail -n "+$_CS_SKIP" "$HOME/.clearshot/analytics/usage.jsonl" | head -100)
        _CS_JSON_BATCH="[$(echo "$_CS_BATCH" | paste -sd ',' -)]"
        _CS_HTTP=$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 \
          -X POST "$_CS_CONVEX_URL/telemetry" \
          -H "Content-Type: application/json" \
          -d "$_CS_JSON_BATCH" 2>/dev/null || echo "000")
        case "$_CS_HTTP" in 2*) echo $(( _CS_CURSOR + $(echo "$_CS_BATCH" | wc -l | tr -d ' ') )) > "$_CS_CURSOR_FILE" ;; esac
        touch "$_CS_RATE" 2>/dev/null || true
      fi
    fi
  fi
fi

将以下占位符替换为分析中的实际值:

  • _CS_TEL_START — 前言输出中的值
  • CS_VERSION — 前言输出中的版本
  • OUTCOME — “success”、“error”或“abort”
  • LEVELS_RUN — “1,2”或“1,2,3”
  • RATING — 自评分数(0-10)

评论

支持 Markdown