eva 特性截图 是做什么的?
一个已发布功能的截图 + 一条推文。无需 Remotion、音乐、编辑或烧录字幕——产品 UI 本身就是资产。
两个文件将存放在仓库根目录的 screenshots/ 中(已加入 .gitignore):
| 文件 | 说明 |
|---|---|
<YYYY-MM-DD>-<slug>.png | 原始 2560×1440 截图——保留它,它是无需重拍的源文件 |
<YYYY-MM-DD>-<slug>-framed.png | 发布这个——3200×1800,带品牌边框 |
带边框的版本将原始截图放置在 eva 的品牌渐变背景上,带有圆角、eva 图标和上方的“Eva”文字标志。这就是为什么截图看起来像产品公告而非 bug 报告截图。
不可协商的默认值
-
1280 布局,以 2560×1440 (16:9) 高清捕获。 脚本驱动真实的 Chrome,设置 deviceScaleFactor 2 并捕获
scale:"device",因此应用以其原生 1280 宽度布局(元素大小可读),但 PNG 像素密度翻倍——在视网膜时间线上清晰锐利。16:9 是 X 在不裁剪的情况下显示在时间线内的比例。输出的帧图像为 3200×1800——同样是 16:9,因此边框在时间线中不占用额外空间。agent-browser 无法做到这一点:其screenshot以 CSS 像素捕获并丢弃 DPR,因此始终输出 1280×720。请使用高清脚本。 -
绝不使用整页截图。 密集应用的整页截图会变成一条长条,在时间线中仅显示缩略图大小。一个视口,一个想法。
-
拍摄前隐藏开发者覆盖层。 react-scan 和 agentation 都会在页面中渲染。
scripts/hd-shot.mjs会处理这一点——使用脚本而非手动链式操作。 -
匹配应用的真实主题。 使用用户当前运行的主题(深色模式用
set media dark)。不要为截图重新设置应用样式。 -
特性必须是视觉主体。 繁忙页面角落的一个 200px 面板是失败的。导航到特性占据主导的视图,或打开包含它的表层(模态框、工作表、详情面板),使其在时间线大小下可读。
侧边栏会自动折叠。
shot.sh(以及普通的hd-shot.mjs --path截图)在捕获前会折叠导航栏——它在 1280px 框架中占用约 250px,其中没有任何内容是特性。仅在侧边栏本身是特性时才传递--no-collapse。在--recipe中,请自行调用ctx.collapseSidebar(page)(配方管理自己的阶段设置)。对于任何辅助列表栏(评论列表、设置导航),如果界面提供隐藏方式,同样适用此规则。在原始 PNG 中验证:如果存在无关导航项的列,请重新拍摄。
-
添加边框,但不要注释。 始终运行第 6 步——渐变 + 文字标志是品牌风格。除非被要求,否则不要添加箭头、红色圆圈、标注文本或虚假的浏览器 chrome。
-
绝不提交。仅输入。 填写输入框,打开选择器,准备好状态——然后拍摄。不要在编辑器中按回车,不要点击发送箭头、创建、保存、运行或开始,绝不启动真实的会话或代理运行,即使是为了更好的截图也不行。提交会改变用户真实的工作空间并消耗真实算力;准备的状态才是你要拍摄的。仅在确认回车只提交到字段本身且不触发其他操作时才允许(例如从打开的选择器接受
@提及)——如果你无法确定,请点击选择器的行。 -
如果数据难看,修复数据——不要绕过它重新拍摄。 默认值 7 阻止你驱动应用产生状态;它不阻止你写入状态。真实的开发数据通常是截图失败的原因:错误墙(“Failed to stop sandbox” ×8)、
Untitled session行、半迁移的状态、特性需要三个样本但只有一个仓库。截图中编辑应用自己的开发数据比寻找偶然看起来好的会话更好,也比重新设置应用样式更好(默认值 4 仍然有效——更改数据,而非 CSS)。直接写入开发部署:使用
npx convex run运行的临时internal/screenshotStaging.ts变更,或 Convex 控制台。为会话赋予真实可读的标题,删除帧中的错误/系统消息,为特性需要的第二行和第三行预填充数据。规则:
- 仅限开发部署。 在写入前确认目标(
npx convex env get CONVEX_URL,或读取.env.local),绝不将阶段变更指向生产环境。 - 首先应是增量和可逆的。 优先修补标题或插入演示行,而非删除真实历史。如果必须删除,先查看行并说明你删除了什么。
- 合理而非虚构具体。 标题和提示看起来像真实工作。绝不编造指标、客户名称或推文随后作为事实重复的数字。
- 截图完成后删除阶段变更——与任何迁移相同的清理规则。
- 在交接时告知用户你更改了什么。
- 仅限开发部署。 在写入前确认目标(
-
保密性。 使用用户自己的仓库
vvedantb/eva。绝不使用客户端仓库(evalucom/carepulse、eprocurement)和列出它们的“Codebases”首页。检查帧内的文档/任务/会话列表中是否有客户端命名的项——如果列表脏乱,请准备一个干净的演示行。绝不在屏幕上对姓名或邮件地址提出个人数据担忧——设置 → 实验中有一个模糊 PID 的开关,它会模糊所有[data-pii]元素,因此产品中已处理。但请标记暴露环境变量名称或项目 ID 的错误面板。
工作流程
-
确定发布了什么。 如果用户未指定哪个特性,请询问——一个问题,而非调查。
git log --oneline -15、git diff --stat或internal/changelog/(最新的月份文件)通常会命名它。你需要特性和展示它的 URL。 -
启动应用。 仅需开发服务器——高清脚本会自行启动自己的 Chrome 并作为代理用户登录(
/?agent=true),在一个设置了 deviceScaleFactor 2 的新上下文中。你不需要驱动 agent-browser 进行拍摄。pnpm dev # 从仓库根目录 → localhost:5173 -
拍摄。 对于纯 URL 截图,
shot.sh会导航、折叠侧边栏、隐藏覆盖层,并以 2560×1440 捕获:bash .claude/skills/eva-feature-screenshot/scripts/shot.sh /vvedantb/eva/web/sessions sessions参数:URL 路径 + slug(+ 可选 settle 毫秒数,+ 可选
--no-collapse)。对于阶段性截图(打开菜单、输入提示,然后捕获),编写一个配方——一个导出
export async function stage(page, ctx)的.mjs文件——并将其传递给hd-shot.mjs。配方负责导航、侧边栏折叠和阶段设置;ctx提供{ BASE, hideOverlays, collapseSidebar, settle }。使用page.getByRole(...)(Playwright)定位器。要找到确切的 accessible name,请先交互式驱动 agent-browser 并使用snapshot -i/read_page。// recipe.mjs — 打开模式选择器并输入提示 export async function stage(page, ctx) { await page.goto(`${ctx.BASE}/vvedantb/eva/web/sessions`, { waitUntil: "networkidle", }); await ctx.settle(3000); await ctx.collapseSidebar(page); await page.getByRole("textbox", { name: /Ask Eva/ }).click(); await page.keyboard.type("重新设计会话侧边栏…"); await page.getByRole("button", { name: "编辑", exact: true }).click(); await ctx.settle(600); }node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug session-modes --recipe /绝对路径/recipe.mjs准备好干净、可读的输入——整洁的演示标题胜过凌乱的真实标题。绝不提交(默认值 7)。
-
读取 PNG 并进行判断。 这是发现糟糕截图的环节:
- 特性是明显的主体,还是淹没在 chrome 中?
- 是否有覆盖层/工具栏残留?是否有骨架屏、旋转加载或
—占位符仍在屏幕上?(增加 settle 毫秒数并重新拍摄。) - 所有四边:是否有裁剪的标签、半渲染的按钮、被切断的列?
- 是否有任何内容违反默认值 9 的保密性?
- 空状态:一个空的看板证明“看板任务”是糟糕的截图。填充数据或选择其他视图。
当由于数据问题(错误墙、
Untitled session、特性需要三个但只有一个行)导致框架失败时,请准备开发数据(默认值 8),而不是寻找更幸运的屏幕。 -
添加边框。
bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> "Eva"写入
screenshots/<今天日期>-<slug>-framed.png(3200×1800)。它通过自己的 Chrome(deviceScaleFactor 2)渲染templates/frame.html——一个与截图分离的浏览器,因此无需事后恢复。也要读取带边框的 PNG——检查渐变是否在角落冲淡了 UI,以及文字标志是否被裁剪。第三个参数可以从另一个路径添加边框到原始 PNG。templates/frame.html是这个技能品牌颜色唯一存在的地方。 -
编写推文。 调用
eva-tweet技能——hook、可选定位片段、→能力列表、可选结尾。截图承载了证明,因此推文陈述现在存在的内容,而非描述图像。绝不引用图像本身。 -
交接。 带边框的文件路径作为 Markdown 链接,推文放在围栏代码块中,以及用户在发布前应检查的帧内任何内容。
快速参考
| 需求 | 命令 |
|---|---|
| 拍摄 URL(高清) | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <路径> <slug> [settle-毫秒数] |
| 保留侧边栏在框架中 | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <路径> <slug> <settle-毫秒数> --no-collapse |
| 阶段性截图(菜单/输入) | node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug <slug> --recipe <绝对路径.mjs> |
| 添加边框(发布这个) | bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> [标题] [原始PNG] |
| 查找 accessible name | 交互式驱动 agent-browser,然后 agent-browser snapshot -i |
| 调试空白/损坏的页面 | agent-browser console · agent-browser errors |
注意事项
- 高清环境在 Playwright 中,而非 agent-browser。 agent-browser 的
screenshot以 CSS 像素捕获并丢弃 devicePixelRatio,因此上限为 1280×720。hd-shot.mjs/hd-frame.mjs使用全局 agent-browser 安装中包含的 playwright-core;如果它位于其他位置,请设置PW_CORE。两者都启动channel:"chrome",因此必须安装系统 Chrome。 - 脚本自行登录 在
/?agent=true(布尔值;/?agent会抛出 zodSearchParamError)的新浏览器上下文中。不需要 agent-browser 会话即可拍摄。 - 开发者覆盖层是三个节点,全部挂在
<html>上,而非<body>。 仅隐藏#react-scan-root是不够的:react-scan 将其组件轮廓和标签绘制在没有任何 id 或 class 的裸html > canvas上,而正是这个 canvas 会破坏截图。hd-shot.mjs使用内联display:none !important杀死所有三个(#react-scan-root、html > canvas、[data-agentation-root]),因为样式表无法胜过它们的内联样式。 - 阶段性截图是一个全新的浏览器,而不是你探索时用的那个。 使用 agent-browser 来查找选择器,但配方会在 Playwright 自己的上下文中重新导航并从头开始准备阶段——将每一步都放在配方中。优先使用
page.getByRole(...)而非 CSS;像@e1这样的引用在这里不存在。 - 两个或更多图像会稀释重点。 X 会将一张图像全宽渲染;第二张会将两者大小减半。仅在真正的之前/之后对比时才拍摄多张。
- 不要重用
video/public/captures/——这些是 Remotion 资产,为不同的任务加边框。