Communitygithub.com

nikserg/skim

根据演示模拟环境重新生成Skim落地页的演示视频和界面截图。当Skim UI发生变化且需要刷新落地页资源时使用。

skim 是什么?

该技能用于在Skim UI发生变更后,自动重新生成产品演示视频以及明/暗两套界面截图,并将这些静态资源发布到 `docs/` 目录下。它通过一个**模拟的Tauri IPC层**(`demo/mock/`)驱动**真实的Skim UI**,因此不会触碰任何真实的账户、邮箱或模型。 技能支持全量运行(`npm run demo`),也支持仅运行截图(`npm run demo:shots`)或仅运行视频(`npm run demo:record && npm run demo:encode`)以加快迭代速度。输出文件包括 `skim-demo.mp4`(1280×800 功能漫游视频)、`skim-light.jpg` 和 `skim-dark.jpg`(800px 宽界面截图)。 该技能不会自动执行 `git add/commit/push`,而是将脏工作树留给用户自行审查——因为二进制文件会产生大 diff,且退出码为0并不保证视频正确。用户需要手动检查三个文件的新 mtime、截图尺寸以及视频各帧的内容,尤其要留意暗色主题下的邮件正文渲染问题。 当 UI 变更导致演示中断时,技能文档提供了详细的故障排查指南:IPC 命令名映射在 `demo/mock/tauri-core.ts` 中,选择器和英文标签在 `demo/record.mjs` 中,模拟数据和 AI 回复在 `demo/mock/data.ts` 中。同时文档还列出了编写录制脚本时容易踩坑的细节(如 composer body 的等待方式、hash 导航后的页面重载、视频保存时机等),帮助开发者快速修复。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/nikserg/skim/tree/HEAD/demo/skill

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

更新 Skim 演示资源

重新生成产品演示视频以及随落地页发布的明/暗两套界面截图。所有操作均由真实的 Skim UI 在模拟的 Tauri IPC 层 (demo/mock/) 上驱动完成,因此绝不会触及真实的账户、邮箱或模型。

输出文件全部发布到 docs/ 目录:

  • skim-demo.mp4 — 脚本化的功能漫游视频 (1280×800)
  • skim-light.jpg, skim-dark.jpg — 界面截图,宽度 800px

不要提交或推送

此技能仅更新磁盘上的文件。不要执行 git add、git commit 或 git push。用户自行审查重新生成的资源,并决定保留哪些内容——这些是二进制文件,会产生较大的 diff,且退出码为 0 的运行结果在视觉上仍可能是错误的。保持工作树脏乱是正确的输出结果。

仅在用户在同一请求中明确要求时才触碰 git(例如“重新生成并提交它们”)。否则,告知用户文件已更新但未暂存。

运行方式

在仓库根目录下执行:

npm run demo

该命令链式执行三个步骤:demo:record(Playwright 驱动真实 UI → demo/output/raw.webm)→ demo:encode(ffmpeg → MP4,复制到 docs/)→ demo:shots(两种主题 → docs/)。

如果仅 UI 部分发生变化,只运行必要的步骤——这样更快,并且能使无关资源保持字节一致:

  • npm run demo:shots — 仅截图(静态 UI、颜色、布局变化)
  • npm run demo:record && npm run demo:encode — 仅视频(流程、AI 行为)

前置条件:已执行 npm install,并且 ffmpeg 在 PATH 中。完整运行需要几分钟;录制是最慢的部分。

npm run demo 以 demo:browser (playwright install chromium) 开始——当浏览器已存在时该步骤为空操作。如果运行失败并提示“Executable doesn't exist at ...chromium_headless_shell-NNNN”,这是因为 Playwright 的浏览器构建版本与库版本不一致(^ 版本提升会重新指向,且 headless shell 是与 Chromium 分开下载的)。执行 npm run demo:browser 或完整的 npm run demo 即可解决此问题,无需将其作为演示问题来调试。单独的 demo:record / demo:shots 脚本会跳过此检查。

在报告成功前进行验证

运行可能以退出码 0 结束,但仍产生损坏的视频。未处理的 mock 命令会返回 undefined 而非抛出异常,这会呈现为空窗格而非错误——所以请相信你的眼睛,而不是退出码。

  1. 确认 docs/ 中的三个文件具有最新的 mtime。
  2. 检查尺寸:截图宽度 800px,MP4 为 1280×800。
  3. 在整个 MP4 中抽取帧并实际查看它们。按比例抽样而非固定秒数——漫游视频的长度会在添加场景或调整节奏时发生变化,因此硬编码的时间戳会失效:
    dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 docs/skim-demo.mp4)
    for k in 1 2 3 4 5 6 7; do
      ffmpeg -y -hide_banner -loglevel error \
        -ss $(echo "$dur * $k / 8" | bc -l) -i docs/skim-demo.mp4 -frames:v 1 /tmp/f$k.png
    done
    
    每一帧都应该显示一个填充好的窗格,AI 场景应该有滚动输出的文本。demo/output/progress.log 会记录每个场景完成时的名称,这有助于将错误帧映射回产生它的步骤。
  4. 查看两张截图——尤其检查暗色主题那张(邮件正文在沙箱化的 iframe 中渲染,有自己的主题逻辑,可能出现暗色背景上的暗色文字)。

报告哪些文件发生了变化以及你看到了什么。如果某个场景看起来有问题,请修复它而不是直接交付。

当 UI 变更导致漫游中断时

测试平台依赖两个约定。失败消息会告诉你哪个约定发生了变动:

IPC 命令名称 (demo/mock/tauri-core.ts)。mock 通过一个 switch 语句实现 invoke(),该 switch 分支对应 src/lib/api.ts 中的命令名称。如果某个命令被重命名或新增,请添加相应的 case。症状:出现空窗格或缺失数据,而非崩溃。

选择器和英文标签 (demo/record.mjs)。漫游会点击诸如 .row、.quick-btn:has-text("Summarize")、.ai-input .instruction 等元素。重命名的 CSS 类或 src/lib/i18n/locales/en.json 中更改的字符串会导致匹配步骤失败,超时错误会指出失败的选择器。演示强制使用 locale: "en",因此英文标签才是关键。

测试数据同样如此:demo/mock/data.ts 会匹配 ai.prompt_* 字符串以决定快速提示对应哪个脚本化的回答,而漫游会等待这些回答中的关键单词(如 "sync"、"yours"、"4.2")。重写测试数据会导致依赖它的等待超时。

所有测试数据和每个脚本化的 AI 响应都位于 demo/mock/data.ts 中——当你希望演示展示不同内容(不同的邮件、不同的摘要、不同的草稿回复)时,这就是需要编辑的文件。

编辑 record.mjs 时非显而易见的陷阱:

  • 编辑器正文是一个 <textarea>。其流式内容是它的 value,而不是它的 text——请使用 waitValue 而非 waitText 进行等待。
  • .compose-window textarea 也会匹配到 AI 指令框(它在 DOM 中排在前面)。对于正文请使用 .compose-window > textarea。
  • 编辑场景通过 hash 导航,并且必须在之后调用 page.reload()——仅 hash 的 goto 不会重新挂载 SPA,因此编辑器永远不会出现。
  • 在 browser.close() 之前 使用 video.saveAs() 保存视频,否则会失败并提示“target closed”。

节奏与主题

默认值针对可读的落地视频进行了调优。可通过环境变量(所有单位均为毫秒)覆盖:DEMO_READ(每屏停留时间)、DEMO_BEAT(动作间间隔)、DEMO_TYPE(按键延迟),以及 DEMO_AI_TYPING / DEMO_AI_THINK / DEMO_AI_STEP(AI 流式输出节奏)。当你在场景中添加内容后感觉节奏过快时,这些变量会很有用。

主题是两维的——"<cold|warm>-<light|dark>",例如 warm-light(应用默认值)。两个脚本都通过 localStorage(skimdemo.theme)强制设置主题,mock 会从 get_settings 返回该主题:

  • 视频固定使用 warm-light;可通过 DEMO_THEME=cold-dark npm run demo:record 覆盖。
  • 截图渲染 warm-light → docs/skim-light.jpg 和 warm-dark → docs/skim-dark.jpg(demo/screenshots.mjs 中的 SHOTS 数组将主题映射为文件名)。

注意遗留的单维值:"light" 和 "dark" 仍然可以解析,但会映射到 cold 调色板,因此传入它们会静默地渲染出错误的色温而非失败。

DEMO_PREBUILT=1 会从 demo/dist-demo 提供静态构建版本,而非使用开发服务器——在受限或无头环境下很方便。

更多细节见 demo/README.md。

相关技能