mcpField
C
clickcast

clickcast

本地服务
github.com/AlexKay28浏览器自动化36 周前更新

关于 clickcast

clickcast 是基于 Playwright 的浏览器自动化工具,面向需要检查网页界面的开发者和 AI Agent。它可自动探索交互元素或执行 YAML 场景,并生成录屏与包含页面状态的 JSON 数据;MCP 模式支持逐步实时操控。

主要功能

  1. 01自动探索页面交互元素
  2. 02执行可重复的 YAML 场景
  3. 03生成 GIF、MP4、WebP 或截图
  4. 04输出带页面状态的 JSON 数据
  5. 05通过 MCP 逐步控制浏览器

适用场景

  1. 01录制网站交互流程供文档使用
  2. 02在 CI 中重复检查前端界面
  3. 03让 Agent 实时浏览并响应页面变化

MCP 相关

clickcast 可作为 MCP 服务运行,通过 stdio 接收 Agent 的浏览器操作,并返回标注画面、页面状态、网格坐标和错误代码。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"alexkay28-clickcast": {
"command": "npx",
"args": [
"-y",
"clickcast-mcp"
]
}
}
}
启动命令npx -y clickcast-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiclickcast0.4.4
npmclickcast-mcp0.4.4

工具

12

收录的工具列表 · 更新于 2 周前

参数类型必填说明
darkany否
gridany否
langany否
deviceany否
engineany否
headfulany否
viewportany否
grid_colorany否
grid_pitchany否
grid_styleany否

详细介绍

🎞️ clickcast — 面向 AI Agent 的 Playwright 浏览器自动化、截图及 GIF/MP4/WebP 录制

为 AI Agent 提供实时 Web UI 的视觉和结构化反馈,同时也为人类生成确定性的演示视频。

PyPI version Python CI License: MIT

最新动态(v0.3.0) — 通过全新的 MCP 服务实现实时 Agent 控制,提供像素级 clickcast diff、融合像素网格叠加层的无障碍语义、官方 CI GitHub Action、首日即提供的 Homebrew/apt 打包,以及可自我修复的首次运行体验。完整更新说明请参阅 CHANGELOG.md。

clickcast · 对 tailwindcss.com 的脚本化浏览之旅 — 固定的 A→B 箭头、右下角的操作面板、对称的打开/关闭操作

请参阅 docs/ONE_PAGE_NAVIGATION_ORDER_TIPS.md,了解这段视频为何如此易读的九项原则,以及可复制用于你自己的演示视频的场景模板。

clickcast 会通过真实浏览器浏览网站,并返回 两项内容:

  1. 可观看的 视频 — GIF / MP4 / WebP / 原始帧。
  2. 机器可读的 JSON 附属文件 — 每个步骤的选择器、计时信息、逐步帧路径、发现的元素,以及操作后的页面状态(标题、URL、控制台错误、失败请求)。带版本管理。请参阅 docs/feedback-schema.md。

提供 URL 后,它会自动发现交互元素并为你生成浏览之旅;也可以传入简短的 YAML 场景,执行脚本化、可重复的浏览流程。


安装

一行命令即可安装,随后便可立即运行:

pip install clickcast && clickcast install --with-deps chromium && clickcast doctor

具体来说,pip install clickcast(需要 Python ≥ 3.10)会安装 CLI;clickcast install 会下载 Chromium(约 180MB,仅需下载一次;由于 Chromium 独立进行版本管理,且并非每个项目都需要每种引擎,因此不会将其打包进 pip 包);--with-deps 还会安装 Chromium 所需的系统库(仅限 Linux,可能会提示输入 sudo);clickcast doctor 会确认上述步骤均已成功完成。

忘了第二步?任何需要浏览器的命令(auto、run、shot、elements、mcp)都会自行检测是否缺少引擎,并当场提供安装选项,而不是直接失败——只需同意一次,它就会自动重试。该提示仅会在交互式终端中出现;CI/脚本化运行会立即失败并显示准确的修复命令,不会卡在标准输入上等待。

Homebrew(macOS/Linux)
brew install --build-from-source ./Formula/clickcast.rb   # works today, clone this repo first
brew install AlexKay28/clickcast/clickcast                # tap not bootstrapped yet -- see docs/packaging/homebrew.md
apt(Debian/Ubuntu,.deb)
bash scripts/build_deb.sh 0.2.9 && sudo dpkg -i dist-deb/clickcast_0.2.9_amd64.deb   # works today, clone this repo first
sudo apt install clickcast                                                           # hosted repo not bootstrapped yet -- see docs/packaging/apt.md

这两种原生软件包都会跳过 Chromium 下载(约 180MB,版本独立于 clickcast),也绝不会额外安装 ffmpeg(clickcast 已通过 imageio[ffmpeg] 捆绑了一个)——采用任一安装方式后,请运行一次 clickcast install --with-deps chromium。完整的设计理念、当前已可用和仍需一次性引导的内容,以及准确的引导步骤,请参阅:docs/packaging/homebrew.md、docs/packaging/apt.md。

npm(clickcast + clickcast-mcp)

两个 npm 包——轻量级 Node 封装,其 postinstall 会创建隔离的 Python venv,并通过 pip 安装固定版本的 PyPI clickcast,因为无法将 clickcast 的 Playwright/Pillow/ffmpeg 运行时作为纯 JS 一并打包。专为 MCP 生态的安装模式 npx <package> 而开发,而非 pip install:

npx -y clickcast-mcp                 # MCP entry point -- execs `clickcast mcp`
npx clickcast --version              # general CLI wrapper

两者均已发布到 npm registry。若要使用你的工作副本而非已发布版本运行:

cd npm/clickcast-mcp && npm pack && npm install -g ./clickcast-mcp-*.tgz && clickcast-mcp --help
cd npm/clickcast      && npm pack && npm install -g ./clickcast-*.tgz      && clickcast --version

完整的设计依据(包括为何共享的配置代码是随包附带的副本,而不是 file: 依赖)、当前已实现的功能与仍需引导配置的部分,以及确切的引导步骤:docs/packaging/npm.md。


面向 AI Agent — 将此提示词复制到聊天中

将下面的代码块粘贴到你的编码 Agent(Claude Code、Cursor、Copilot Chat、Codex 等)中,只需一条消息即可教会它使用 clickcast。Agent 将安装工具、验证环境、为你的项目生成可视化和机器可读报告,并了解如何根据结果设置 CI 门禁。

You are going to use `clickcast` (https://pypi.org/project/clickcast/) to visually verify
this project's frontend. It produces a watchable GIF reel + a JSON sidecar with
per-step selectors, timings, page state, error codes, and a graph of the app's
pages. Follow this exact sequence:

1. INSTALL
   pip install clickcast
   clickcast install --with-deps chromium   # first time only, ~180 MB
   clickcast doctor                          # bail out if this fails

2. LOAD FULL CAPABILITIES
   Run `clickcast skill --json` and read the output. It lists every subcommand,
   flag, docs URL, and sidecar schema pointer. Prefer this over guessing.

3. RUN A QUICK TOUR OF THE APP
   If we have a running URL (dev server / staging / production):
     clickcast auto <URL> --for-humans --emit-events --out tour.gif
   If we have a specific flow to verify, write a YAML scenario and run:
     clickcast run tour.yml --emit-events --out tour.gif
   `--for-humans` gives a legible reel for the user to watch;
   `--emit-events` prints a machine-readable JSONL line you can parse.

4. READ THE SIDECAR (JSON at `<gif>.json`, schema v3)
   For each step, gate on the structured fields — NOT regex over prose:
     - `status`      : "ok" | "failed" | "skipped"
     - `error_code`  : "timeout" | "locator_missing" | "cross_origin" |
                       "navigation_error" | "selector_ambiguous" | "other"
     - `skip_reason` : "optional_no_reaction" | "pre_action_failed" |
                       "element_vanished" | "cross_origin_bounce"
     - `page_state`  : title, url_after, console_errors, page_errors,
                       network_failed
   The top-level `graph` block gives page nodes + navigation edges you can
   use to reason about the app's shape, not just the sequence you ran.

5. WATCH STDERR FOR ADVISORIES
   clickcast prints `⚠ <message> — see <docs-url>` lines for known anti-
   patterns (nav-heavy tour, click without DOM reaction, very short reel,
   cross-origin bounce, incoherent cursor styling). Each has a stable
   kebab-case id you can dedupe or gate on.

6. FOR CI REGRESSION GATES
   `clickcast assertions <sidecar>.json --baseline golden.json` diffs the
   run against a committed baseline; nonzero exit on drift. Byte-identical
   across runs (timestamps, frame paths, and URL query strings excluded).

Reference docs (all in-repo, load lazily as needed):
  - Sidecar shape:   https://github.com/AlexKay28/clickcast/blob/main/docs/feedback-schema.md
  - Human-legible reel authoring: https://github.com/AlexKay28/clickcast/blob/main/docs/ONE_PAGE_NAVIGATION_ORDER_TIPS.md
  - Agent integration:  https://github.com/AlexKay28/clickcast/blob/main/docs/ai-integration.md

If something is unclear, run `clickcast <subcommand> --help` before asking me.

完成后,可以向 Agent 提出具体要求,例如 “针对 http://localhost:3000 运行 clickcast auto,并告诉我哪些点击触发了 DOM 响应”——它现在已掌握所需的一切。


实时 Agent 控制(MCP)

以上所有内容都是批处理模式:录制完整的浏览过程,然后读取 GIF 和配套文件。clickcast mcp 是实时对应模式——一个一次驱动一个操作(goto/click/type/scroll/...)的 MCP 服务,并返回 clickcast 更丰富的单次调用负载(带注释的帧、page_state、网格坐标、枚举型 error_code),而不是一张简单截图,因此 Agent 可以先做出响应,再决定下一步操作。

pip install 'clickcast[mcp]'
{
  "mcpServers": {
    "clickcast": { "command": "clickcast", "args": ["mcp"] }
  }
}

当 Agent 需要实时探索并做出响应时,使用 mcp;需要可重复、一次性生成的产物(CI、文档、发行说明)时,使用 auto/run。完整工具参考、Claude Code / Claude Desktop 的客户端配置以及架构文档:docs/mcp.md · docs/mcp-tool-schema.md。


首次运行 — 30 秒

clickcast auto https://example.com --out tour.gif

生成两个文件:

  • tour.gif — 动图
  • tour.gif.json — AI 可读取的配套文件(schema_version: 1,规范见 docs/feedback-schema.md)

有关 LLM Agent 如何使用这两个文件的演示,请参阅 docs/ai-integration.md。


三种模式

模式命令适用场景
自动clickcast auto <url>快速浏览网站;不需要精确控制脚本。
场景clickcast run tour.yml精确、可重复的浏览流程。文档、发行说明、CI。
截图clickcast shot <url>单张截图,可截取视口或整页。

三种模式均为确定性运行,默认采用无头模式,并适合用于 CI。


命令

auto <url>

发现交互元素并录制点击浏览过程。

标志默认值说明
--out PATHreel.gif文件扩展名决定格式。
--max-steps N / -N10限制要点击的已发现元素数量。
--dwell SEC1.0每次操作后的停留时间。
--initial-wait SEC2.0networkidle 后的等待时间,让 SPA 完成加载。
--viewport WxH1280x800
--device NAME–Playwright 预设(例如 "iPhone 15"、"Pixel 8")。
--engine Echromiumchromium / firefox / webkit。
--headful关闭显示真实浏览器窗口。
--lang LOCALE–例如 en-US。
--dark关闭模拟 prefers-color-scheme: dark。
--fps N12
--format F–覆盖根据扩展名推断的格式。
--quality 1..308数值越低,质量越好(保真度更高,文件更大)。
--loop N00 = 无限循环。
--no-sidecar关闭跳过 JSON 文件。
-v / --verbose–可重复指定。
run <scenario.yml>

执行 YAML 场景。参见场景格式。

clickcast run docs/scenarios/spa.yml \
    --out release-notes.mp4 --format mp4 \
    --var base_url=https://staging.example.com

标志:--out、--format、--headful、--slowmo MS、--url URL(重新指定第一个 goto 步骤的目标网址——见下文)、--var key=value(可重复使用——在场景中替换 {{ key }})、--no-sidecar。

CLI 标志会覆盖场景的 meta: 块。

使用 --url 将现有场景指向不同的环境——无需编辑 YAML,也无需使用 {{ URL }} 模板:

clickcast run tour.yml --url https://staging.example.com/app

--url 会重写第一个 goto 步骤的网址,且优先级高于 --var URL=...。它只会影响第一个 goto——后续的 goto 步骤通常是在入口点之后进行的应用内导航,因此保持不变。

shot <url>

单张截图。

clickcast shot https://example.com --full-page --out home.png

标志:--out、--full-page、--wait(load / domcontentloaded / networkidle / 选择器 / 秒数)、--viewport、--device、--engine、--dark。

init [path]

生成一个 YAML 场景起始模板。--from-auto 会运行一次发现流程,并用得分最高的点击步骤填充文件。

clickcast init tour.yml --url https://example.com --from-auto

标志:--url、--name、--out、--from-auto、--force。

elements <url>

列出发现的交互元素——有助于编写选择器。 每个条目还包含一个 accessibility 块(Playwright 自带的 role / 可访问名称 / 交互state,以及启用 --grid 时像素网格 叠加层中的 grid_cell)——参见 docs/feedback-schema.md。

clickcast elements https://example.com --json > elements.json
clickcast elements https://example.com --grid --grid-pitch 50 --json
标志默认值说明
--limit N20返回元素数量上限。
--json关闭在 stdout 输出机器可读的 JSON。
--viewport WxH1280x800
--device NAME–Playwright 预设(例如 "iPhone 15"、"Pixel 8")。
--engine Echromiumchromium / firefox / webkit。
--headful关闭显示真实浏览器窗口。
--lang LOCALE–例如 en-US。
--dark关闭模拟 prefers-color-scheme: dark。
--slowmo MS0每次 Playwright 操作延迟 N 毫秒。
-v / --verbose–可重复使用。
--grid关闭填充每个元素的 accessibility.grid_cell(#196)。
--grid-pitch N100主网格线的像素间距,用于 grid_cell。
--grid-color HEX#FFFFFF33除验证外,elements 不会使用此选项——为与 auto/run/shot 保持一致而保留。
--grid-style full|rulerfull除验证外,elements 不会使用此选项——为与 auto/run/shot 保持一致而保留。
doctor

检查 Python 版本、playwright、引擎二进制文件、ffmpeg 和配置路径。

clickcast doctor           # human-readable
clickcast doctor --json    # machine-readable, non-zero exit on failure
config

读取 / 写入持久默认值。

clickcast config path                    # print the user config file path
clickcast config list                    # every effective value + source
clickcast config get engine
clickcast config set engine firefox

设置值会写入用户 TOML 文件,路径为 clickcast config path。优先级请参见配置。

install [engines…]

对 playwright install 的封装。默认引擎:chromium。

clickcast install                        # chromium only
clickcast install firefox webkit         # add more
clickcast install --with-deps chromium   # Linux: pull system libs (needs sudo)
mcp

启动用于实时 Agent 控制的 stdio MCP 服务——参见上文实时 Agent 控制(MCP)和docs/mcp.md。需要执行 pip install 'clickcast[mcp]'。

clickcast mcp --grid   # every action tool's returned frame carries the coordinate overlay

标志:--engine、--viewport、--device、--headful、--lang、--dark、--grid/--grid-pitch/--grid-color/--grid-style——当连接的 Agent 未覆盖这些默认值时,它们将作为 start_session 的默认值。


场景格式

场景是纯 YAML:包含一个 meta: 块和一个 steps: 列表。完整示例见:docs/scenarios/。

meta:
  name: WorldSight broad tour
  engine: chromium              # chromium | firefox | webkit
  viewport: 1280x800
  device: null                  # or "iPhone 15", "Pixel 8", "iPad Pro"
  fps: 12
  dwell: 1.0                    # default seconds after each step
  format: gif                   # gif | mp4 | webp | frames
  out: worldsight.gif

steps:
  - goto: https://worldsight-weld.vercel.app
    wait: networkidle
    label: Open WorldSight

  - click: "text=3D"
    label: Switch to 3D globe
    dwell: 2.0

  - hover: "[aria-label='Rankings']"
  - click: "[aria-label='Rankings']"
    label: Open Rankings

  - type:
      into: "#search"
      text: "Japan"
    label: Search Japan

  - select:
      in: "#metric"
      value: "GDP"

  - scroll:
      to: footer
支持的操作
操作示例说明
gotogoto: https://…导航。与 wait 配合使用。
clickclick: "text=Compare"CSS、text=… 或 role=… 选择器——Playwright 语法。也接受 click: { selector: ..., wait: networkidle }——wait(与 goto 的格式相同)会在点击后等待;与触发客户端/SPA 导航的目标搭配使用。
dblclickdblclick: ".cell"也接受 wait,与 click 相同。
hoverhover: ".menu"显示 CSS :hover 状态。
typetype: { into: "#q", text: "Japan", delay: 40 }delay 的单位为毫秒,每个字符都会应用此延迟。
presspress: "Enter"或 press: { key: "Ctrl+A", selector: "#in" }。
selectselect: { in: "#m", value: "GDP" }在 YAML 中使用 in: → 内部会转换为 into。
scrollscroll: { to: "footer" } 或 scroll: { by: 600 }按元素或像素滚动。
waitwait: 1.5 或 wait: networkidle 或 wait: ".map-loaded"数字表示秒数;字符串表示加载状态或选择器。
screenshotscreenshot: { full_page: true }强制截取一帧。

每个步骤也都接受 label、dwell、optional: true(如果找不到选择器,不会导致运行失败——sidecar 会记录 status: "skipped")和 repeat: N。

变量替换:任何字符串中的 {{ key }} 都会被替换,变量通过 --var key=value 注入。


Python API

流畅、可链式调用——每个构建器都会返回 self:

from clickcast import Reel

reel_path = (
    Reel("https://worldsight-weld.vercel.app", viewport=(1280, 800), fps=12)
    .goto(wait="networkidle")
    .click("text=3D", label="Switch to 3D globe", dwell=2.0)
    .click("[aria-label='Rankings']", label="Open Rankings")
    .scroll(to="footer")
    .save("worldsight.gif")  # or .save("tour.mp4", quality=8)
)

适用于已在运行事件循环中的调用方的异步变体:

from clickcast import AsyncReel

reel = AsyncReel("https://example.com").goto(wait="networkidle").click("#cta")
path = await reel.save("tour.gif")

仅发现,不生成录制文件:

from clickcast import discover

elements = discover("https://example.com", limit=10)

使用 save(..., no_sidecar=True) 跳过 sidecar。


推送前在本地静态构建上迭代

正在构建静态网站,并在推送前于本地录制?使用 Reel.serve_dir(或独立的 serve_directory 辅助函数)作为上下文管理器——它会在空闲端口上启动多线程 HTTP 服务,返回基础 URL,并在退出时关闭服务。再也不必调用 python3 -m http.server 8091 &,导致服务进程在 shell 会话结束后仍残留,并与下一轮迭代的端口冲突。

from clickcast import Reel

with Reel.serve_dir("./public") as url:
    Reel(url).goto().click(".chip").save("out.gif")
# Server is gone; the port is free.

默认设置适用于安全的开发迭代:仅绑定回环地址(127.0.0.1)、由操作系统选择空闲端口、使用 ThreadingHTTPServer,避免并行浏览器请求排队。可显式覆盖其中任何设置:

from clickcast.serving import serve_directory  # importable without going through Reel

with serve_directory("./dist", port=8091, bind="0.0.0.0", threading=False) as url:
    ...

bind="0.0.0.0" 会将服务暴露给局域网——需主动启用,并非默认设置。


读取 sidecar

每次录制运行都会在媒体文件旁写入 <out>.json。

from clickcast.feedback import load

report = load("tour.gif.json")

for step in report.steps:
    if step.status == "failed":
        print(f"step {step.index} ({step.action}) failed: {step.error}")
        print("  frames:", step.frames)
        if step.page_state:
            print("  console errors:", step.page_state.console_errors)

不想导入 clickcast 的使用方可以直接根据 src/clickcast/feedback/schema/v1.json 中的架构解析 JSON。独立的参考实现位于 tests/consumer/read_sidecar.py。

请参阅 docs/ai-integration.md,了解两行代码的 Agent 集成示例;并参阅 docs/feedback-schema.md,了解逐字段的完整说明。


CI:2 行回归门禁

在 GitHub Actions 上使用?.github/actions/clickcast 将此方案(以及下方的可视化 diff 门禁、浏览器缓存, 还有包含录屏和摘要表格的 PR 评论)打包成了一个可复用的 Action — 参见 docs/ci/README.md。对于其他 CI 平台,以及不想 为了两行 shell 命令而依赖第三方 Action 的用户,本节仍是标准方案。

每段录屏都会写入一个 JSON 旁文件,但原始旁文件包含时间戳、帧 文件名和查询字符串令牌 — 这些内容在不同运行之间都不稳定。要设置 合适的 CI 回归门禁,请使用 clickcast assertions(或 Reel.assertions()),将旁文件精简为真正重要的结构:步骤数量、每步的 操作 / 标签 / 状态,以及每步的错误计数器。

对于同一 URL 上的同一场景,精简后的结构在不同运行之间逐字节相同(架构: docs/assertions-schema/v1.json)。 将其与已提交的基线进行比较;发生偏差时以非零状态退出。

只需初始化一次基线:

clickcast run tour.yml --out reel.gif
clickcast assertions reel.gif.json > tests/golden-tour.json  # commit this

然后在 CI 中(2 行):

clickcast run tour.yml --out reel.gif
clickcast assertions reel.gif.json --baseline tests/golden-tour.json

退出码为 0 表示目标 UI 产生的步骤顺序、状态和错误信号计数,与捕获 基线时相同;其他情况都属于真实偏差,命令会打印逐行说明,例如 step 2: status changed 'ok' -> 'failed'。

Python 中的相同信号:

from clickcast import Reel

reel = Reel(url).goto().click(".cta").save("reel.gif")
drift, is_clean = reel.assertions_diff("tests/golden-tour.json")
if not is_clean:
    raise SystemExit("\n".join(drift))

精简结构会有意排除以下内容:墙上时钟时间戳、 每步的 duration_ms、frames 文件名、解析后的 URL(包括查询字符串令牌)、 cursor_xy。如果门禁也需要这些内容, 请使用自己的工具比较原始旁文件 — 断言集是狭义的“UI 行为是否仍然正常” 契约,而不是线级快照。

它的可视化搭档:clickcast diff

assertions 是结构化检查 — 完全不会查看像素。clickcast diff (以及 Reel.visual_diff())是像素级搭档:它会将两个 旁文件中的步骤配对,并对比它们的帧像素,报告变化像素百分比 和每步变化区域列表,还会生成突出显示区域的差异图像。用 assertions 检查“流程出问题了”(步骤数量不对、某步开始失败);用 diff 检查“流程 正常运行,但按钮移位 / 颜色改变 / 布局偏移。” 两者可以组合 — 在 CI 中同时运行以全面覆盖;如果只关心 像素偏差,则单独运行 diff。

clickcast diff reel.gif.json tests/golden-tour.gif.json \
  --out diff-report --fail-above 5

当任一步骤的变化像素百分比超过 --fail-above,或某个步骤无法与其基线对应步骤配对时,命令会以非零状态退出 (步骤数量不匹配时会回退到按标签匹配; 仍未匹配的步骤会被标记,而不会静默跳过)。 --out 会将突出显示区域的差异图像以及一个 summary.json 收集为 CI 构件;--threshold 用于调整逐像素噪声阈值。默认情况下,Clickcast 自身的叠加层(进度条、操作标签、操作面板、光标 + 涟漪) 会从差异比较中排除 — 否则每次运行都会将自身的界面标记为回归 — 若要进行严格的 原始像素比较,请传入 --no-exclude-overlays。Python 中的相同信号可通过 reel.visual_diff(run_path, baseline_path) 获取。


配置

优先级(从高到低):

  1. CLI 标志
  2. 场景 meta: 块
  3. CLICKCAST_* 环境变量
  4. 项目 ./clickcast.toml
  5. 用户 TOML(路径通过 clickcast config path 获取)
  6. 内置默认值

每个 Config 字段都可以在上述任意层设置:engine、viewport、device、headful、slowmo、lang、dark、proxy、fps、dwell、format、quality、loop。

项目 TOML — 扁平格式或使用 [defaults] 包装的格式均可:

# clickcast.toml
engine   = "chromium"
viewport = "1280x800"
fps      = 12
dwell    = 1.0
format   = "gif"

环境变量:

CLICKCAST_ENGINE=firefox
CLICKCAST_VIEWPORT=1440x900
CLICKCAST_HEADFUL=true
CLICKCAST_PROXY=http://proxy.internal:8080

输出格式

格式适用场景说明
gifREADME、聊天、快速分享兼容性最广;文件较大。
mp4文档站点、社交媒体、长篇演示时长较长时文件最小;使用 imageio-ffmpeg 随附的二进制文件。
webp网页嵌入文件大小和质量都很出色;支持动画。
frames自定义流水线带编号的 PNG 文件 + frames.json 清单。

--quality 1..30 用文件大小换取保真度(数值越低 = 质量越好)。--loop 0 无限循环;--loop 1 播放一次。


工作原理

   URL ─▶ Session ─▶ Actions ─▶ Recorder ─▶ Encoder ─▶ .gif/.mp4/.webp
        (chromium)  (auto or   (per-step   (Pillow /
                     YAML)      PNGs +      imageio-
                                manifest)   ffmpeg)
                        │           │
                        ▼           ▼
              PageStateCollector    ─▶ ReportBuilder ─▶ <out>.json
                (console errors,
                 page errors,
                 failed requests)
  1. Session 在指定的视口/设备上启动 Playwright 浏览器。
  2. Actions 一次执行一个步骤(click、type、scroll,……),并使用标准化的时间安排和光标跟踪。
  3. Recorder 为每个步骤捕获一帧预览帧 + N 帧填充帧(文件名确定;填充帧为逐字节相同的副本)。
  4. PageStateCollector 订阅页面事件,为伴随文件收集数据。
  5. Encoder 生成最终产物;ReportBuilder 完成 JSON。

标注器(clickcast.annotate.Annotator — 点击涟漪、光标轨迹、字幕栏、进度栏)在 v0.1 中以库 API 的形式提供。计划在 v0.2 中自动接入 auto / run 输出(参见路线图)。


故障排除

  • 空白帧 — 该网站是 SPA;请增加 --initial-wait,或在第一步中添加 wait: networkidle(或特定选择器)。
  • 找不到 ffmpeg — imageio-ffmpeg 会附带静态二进制文件;若缺失则会回退。若想完全跳过 MP4,请选择 gif / webp。
  • 找不到选择器 — clickcast elements <url> 会显示实际可点击的元素。也可以将该步骤标记为 optional: true。
  • 无法访问内网站点 — 设置 CLICKCAST_PROXY,或在场景的 meta: 块中设置 proxy。
  • 缺少 Chromium — 运行 clickcast install。在 Linux CI 中添加 --with-deps。
  • 伴随文件结构已更改 — 当前架构的版本化定义位于 src/clickcast/feedback/schema/v1.json;未来的 v2(参见 #29)将添加 graph 块,同时保持对 v1 使用方的兼容。

贡献

git clone https://github.com/AlexKay28/clickcast
cd clickcast
pip install -e ".[dev]"
clickcast install

提交 PR 前:

ruff check .
ruff format --check .
mypy
pytest -m "not integration"      # fast; ~2s
pytest                            # full; needs chromium

发布流程记录在 RELEASING.md 中。


路线图

v0.1(本次发布):Session · Actions · Recorder · Encoder · Discovery · YAML 场景 · CLI · Python API · 伴随文件(架构 v1)· 配置优先级 · Fixture 测试站点 · 文档。

v0.2(计划中 — 见 #29):

  • 帧内 HUD — 固定页眉/页脚,显示步骤索引、操作动词、目标角色、URL。可被 OCR 识别,因此大模型可以将录像读作一组图像。
  • BFS UI 探索 — clickcast explore <url> 将应用视为状态图:发现 → 点击 → 发现新状态 → 递归。设有边界、结果确定,并对已访问状态去重。
  • 伴随文件架构 v2 — 添加顶层 graph 块(节点 = 不同的页面状态,边 = (from, to, action, transition_kind))。
  • 自动标注 auto / run 输出。

相关项目

vercel-labs/webreel — 一款用于创作精美演示视频的 TypeScript 工具。鉴于名称相似、输出也有重叠,容易与本项目混淆,因此说明如下:clickcast 是一款 Python 工具,主要面向需要通过视觉模态处理实时 Web UI 的 AI Agent,其次面向希望制作可复现演示视频的人类用户。如果你想制作手工编排的营销视频,webreel 会更适合。


许可证

MIT © 2026 Alex Kay。详见 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。