clickcast について
clickcastは、Webインターフェースを調べる開発者やAIエージェント向けのPlaywrightベースのブラウザー自動化ツールです。操作要素の自動検出やYAMLシナリオの実行ができ、録画とページ状態を含むJSONを生成します。MCPモードでは一手ずつリアルタイムに操作できます。
主な機能
- 01ページ内の操作要素を検出
- 02再現可能なYAMLシナリオを実行
- 03GIF、MP4、WebP、スクリーンショットを作成
- 04ページ状態付きJSONを出力
- 05MCP経由でブラウザーを逐次操作
活用シーン
- 01ドキュメント用にWebサイトの操作を記録
- 02CIでフロントエンドの確認を繰り返す
- 03エージェントにページを探索・応答させる
MCP 対応
stdio経由のMCPサーバーとして動作し、エージェントからブラウザー操作を受け取り、注釈付きフレーム、ページ状態、グリッド座標、エラーコードを返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
12掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| dark | any | いいえ | |
| grid | any | いいえ | |
| lang | any | いいえ | |
| device | any | いいえ | |
| engine | any | いいえ | |
| headful | any | いいえ | |
| viewport | any | いいえ | |
| grid_color | any | いいえ | |
| grid_pitch | any | いいえ | |
| grid_style | any | いいえ |
詳細
🎞️ clickcast — AI エージェント向けの Playwright ブラウザー自動化、スクリーンショット、GIF/MP4/WebP 録画
AI エージェントに、実際に動作している Web UI の視覚的かつ構造化されたフィードバックを提供しながら、人間向けの再現性の高いデモリールも作成できます。
新機能(v0.3.0) — 新しい MCP サーバーによるエージェントのリアルタイム操作、ピクセルレベルの
clickcast diff、ピクセルグリッドオーバーレイと統合されたアクセシビリティセマンティクス、公式 CI GitHub Action、初日から利用できる Homebrew/apt パッケージ、初回実行時の自己修復機能を追加しました。詳細はCHANGELOG.mdをご覧ください。

このリールが読みやすい理由となる 9 つの原則と、自分のリールにコピーできるシナリオテンプレートについては、
docs/ONE_PAGE_NAVIGATION_ORDER_TIPS.mdをご覧ください。
clickcast は実際のブラウザーを使って Web サイトを操作し、次の 2 つを返します。
- 視聴できる リール — GIF/MP4/WebP/生フレーム。
- 機械可読な JSON サイドカー — 各ステップのセレクター、タイミング、ステップごとのフレームパス、検出した要素、アクション後のページ状態(タイトル、URL、コンソールエラー、失敗したリクエスト)。バージョン管理されています。詳しくは
docs/feedback-schema.mdをご覧ください。
URL を指定すると、インタラクティブ要素を 自動検出 してツアーを作成します。または、小さな YAML シナリオを渡せば、スクリプト化された再現可能なウォークスルーを実行できます。
インストール
1 行実行すれば、すぐに使えます。
pip install clickcast && clickcast install --with-deps chromium && clickcast doctor
手順の内訳 — pip install clickcast(Python ≥ 3.10 が必要)で CLI をインストールします。clickcast install で Chromium をダウンロードします(約 180MB、基本的には一度だけ。バージョンが別個に管理され、すべてのプロジェクトがすべてのブラウザーエンジンを必要とするわけではないため、pip パッケージには含まれていません)。--with-deps を指定すると、Chromium が必要とするシステムライブラリもインストールします(Linux のみ。sudo の実行を求められる場合があります)。clickcast doctor で、ここまでの手順がすべて正常に完了したことを確認できます。
2 つ目の手順を忘れた場合も問題ありません。ブラウザーが必要なコマンド(auto、run、shot、elements、mcp)は、ブラウザーエンジンがないことを自動検出し、失敗する代わりにその場でインストールを提案します。一度承認すれば、自動で再試行します。このプロンプトは対話型ターミナルでのみ表示されます。CI/スクリプト実行では stdin で停止せず、正確な修正コマンドを表示してすぐに終了します。
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 とは別個に管理)を省略し、2 つ目の ffmpeg はインストールしません(clickcast には imageio[ffmpeg] 経由ですでに同梱されています)。いずれかの方法でインストールした後、clickcast install --with-deps chromium を一度実行してください。設計の詳しい背景、現時点で利用できる機能と一度だけ初期設定が必要な機能、その正確な初期設定手順については、docs/packaging/homebrew.md と
docs/packaging/apt.md をご覧ください。
npm(clickcast + clickcast-mcp)
2 つの npm パッケージです。薄い Node ラッパーであり、postinstall によって分離された Python venv を用意し、バージョンを固定した PyPI の clickcast を pip でインストールします。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 レジストリで公開されています。公開版ではなく、手元の作業コピーに対して実行するには、次のようにします。
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 エージェント向け — このプロンプトをチャットにコピーしてください
以下のブロックをコーディングエージェント(Claude Code、Cursor、Copilot Chat、Codex など)に貼り付けて、1 つのメッセージで clickcast の使い方を教えてください。エージェントはツールをインストールして環境を検証し、プロジェクトの視覚的かつ機械可読なレポートを生成し、結果に基づいて 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.
エージェントにこれを設定したら、「http://localhost:3000 に対して clickcast auto を実行して、DOM の反応があったクリックを教えて」 のように、具体的なことを尋ねてください。必要なものはすべて揃っています。
ライブエージェント制御(MCP)
ここまでの内容はすべてバッチモードです。ツアー全体を記録してから、GIF とサイドカーを読み返します。clickcast mcp はライブ版で、1 回に 1 つのアクション(goto/click/type/scroll/...)を実行する MCP サーバーです。単なるスクリーンショットではなく、clickcast のより豊富な呼び出しごとのペイロード(注釈付きフレーム、page_state、グリッド座標、列挙された error_code)を返すため、エージェントは次のステップを決める前に反応できます。
pip install 'clickcast[mcp]'
{
"mcpServers": {
"clickcast": { "command": "clickcast", "args": ["mcp"] }
}
}
エージェントにライブで探索しながら反応させる場合は 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
次の 2 つのファイルを生成します。
tour.gif— リールtour.gif.json— AI が利用できるサイドカー(schema_version: 1。仕様はdocs/feedback-schema.mdを参照)
LLM エージェントが両方をどのように利用するかを順を追って説明したものは、docs/ai-integration.md を参照してください。
3 つのモード
| モード | コマンド | 用途 |
|---|---|---|
| 自動 | clickcast auto <url> | サイトを手早く一巡します。正確なスクリプトは不要な場合に使います。 |
| シナリオ | clickcast run tour.yml | 正確で再現可能なウォークスルーを実行します。ドキュメント、リリースノート、CI 向けです。 |
| ショット | clickcast shot <url> | ビューポートまたはページ全体のスクリーンショットを 1 枚撮影します。 |
3 つすべてのモードは決定的で、デフォルトではヘッドレスで動作し、CI に適しています。
コマンド
auto <url>
インタラクティブな要素を検出し、クリックツアーを記録します。
| フラグ | デフォルト | 説明 |
|---|---|---|
--out PATH | reel.gif | 拡張子によって形式が決まります。 |
--max-steps N / -N | 10 | クリックする検出済み要素数の上限です。 |
--dwell SEC | 1.0 | 各アクション後の待機時間です。 |
--initial-wait SEC | 2.0 | SPA のハイドレーションを待つため、networkidle 後に待機する時間です。 |
--viewport WxH | 1280x800 | |
--device NAME | – | Playwright のプリセット(例:"iPhone 15"、"Pixel 8")です。 |
--engine E | chromium | chromium/firefox/webkit です。 |
--headful | オフ | 実際のブラウザーウィンドウを表示します。 |
--lang LOCALE | – | 例:en-US。 |
--dark | オフ | prefers-color-scheme: dark をエミュレートします。 |
--fps N | 12 | |
--format F | – | 拡張子から決まる形式を上書きします。 |
--quality 1..30 | 8 | 数値が小さいほど高品質(忠実度が高く、ファイルサイズが大きい)になります。 |
--loop N | 0 | 0 は無限ループです。 |
--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 ステップの URL を変更します。以下を参照)、--var key=value(繰り返し指定可能。シナリオ内の {{ key }} を置換します)、--no-sidecar。
CLI フラグはシナリオの meta: ブロックより優先されます。
--url を使うと、YAML を編集したり {{ URL }} のテンプレートを使ったりせずに、既存のシナリオの実行先環境を変更できます。
clickcast run tour.yml --url https://staging.example.com/app
--url は最初の goto ステップの URL を書き換え、--var URL=... より優先されます。変更されるのは最初の goto のみです。後続の goto ステップは通常、開始地点からのアプリ内ナビゲーションなので、そのまま維持されます。
shot <url>
スクリーンショットを 1 枚撮影します。
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 を指定すると、検出を 1 回実行し、スコア上位のクリック手順をファイルに追加します。
clickcast init tour.yml --url https://example.com --from-auto
フラグ:--url、--name、--out、--from-auto、--force。
elements <url>
検出されたインタラクティブ要素を出力します。セレクターの作成に便利です。
各項目にはさらに accessibility ブロックが含まれます(Playwright 独自の
role/アクセシブルな name/インタラクティブな 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 N | 20 | 返される要素の上限です。 |
--json | off | 機械可読な JSON を標準出力に出力します。 |
--viewport WxH | 1280x800 | |
--device NAME | – | Playwright のプリセットです(例:"iPhone 15"、"Pixel 8")。 |
--engine E | chromium | chromium/firefox/webkit。 |
--headful | off | 実際のブラウザーウィンドウを表示します。 |
--lang LOCALE | – | 例:en-US。 |
--dark | off | prefers-color-scheme: dark をエミュレートします。 |
--slowmo MS | 0 | Playwright の各操作を N ミリ秒遅らせます。 |
-v / --verbose | – | 繰り返し指定できます。 |
--grid | off | 各要素の accessibility.grid_cell を設定します(#196)。 |
--grid-pitch N | 100 | grid_cell に使われる主線の間隔(px)です。 |
--grid-color HEX | #FFFFFF33 | 検証以外では elements で使われません。auto/run/shot と対称性を保つために用意されています。 |
--grid-style full|ruler | full | 検証以外では 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
エージェントをリアルタイムに制御するための stdio MCP サーバーを起動します。前述のリアルタイムエージェント制御(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。接続するエージェントが別の値を指定しない場合、これらはすべて 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
サポートされているアクション
| アクション | 例 | 備考 |
|---|---|---|
goto | goto: https://… | 移動します。wait と組み合わせてください。 |
click | click: "text=Compare" | CSS、text=…、または role=… セレクターに対応しています(Playwright 構文)。click: { selector: ..., wait: networkidle } も指定できます。wait(goto の場合と同じ形式)はクリック後に処理をブロックします。クライアント側または SPA のナビゲーションを発生させる対象と組み合わせてください。 |
dblclick | dblclick: ".cell" | click と同様に wait も指定できます。 |
hover | hover: ".menu" | CSS の :hover 状態を表示します。 |
type | type: { into: "#q", text: "Japan", delay: 40 } | delay は文字ごとのミリ秒です。 |
press | press: "Enter" | press: { key: "Ctrl+A", selector: "#in" } のようにも指定できます。 |
select | select: { in: "#m", value: "GDP" } | YAML の in: は内部で into に変換されます。 |
scroll | scroll: { to: "footer" } または scroll: { by: 600 } | 要素またはピクセル単位でスクロールします。 |
wait | wait: 1.5 または wait: networkidle または wait: ".map-loaded" | 数値は秒数、文字列は読み込み状態またはセレクターです。 |
screenshot | screenshot: { full_page: true } | フレームのキャプチャを強制します。 |
各ステップでは、label、dwell、optional: true(セレクターが見つからなくても実行を失敗させず、サイドカーに 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) を指定すると、サイドカーを省略できます。
プッシュ前のローカル静的ビルドでの反復作業
静的サイトをビルドし、プッシュする前にローカルでリールを作成しますか?Reel.serve_dir(または単独の serve_directory ヘルパー)をコンテキストマネージャーとして使用してください。空いているポートでスレッド化された HTTP サーバーを起動し、ベース URL を返して、終了時にサーバーを停止します。シェルセッション終了後もプロセスが残ったり、次の反復作業でポートが競合したりする python3 -m http.server 8091 & の実行は不要です。
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)、OS による空きポートの選択、並列のブラウザーリクエストが滞留しない 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" を指定すると、サーバーが LAN に公開されます。デフォルトではなく、明示的に指定する必要があります。
サイドカーの読み込み
記録を実行するたびに、メディアファイルと並んで <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 をインポートしたくない利用側は、JSON を src/clickcast/feedback/schema/v1.json のスキーマに照らして直接解析できます。単独で使用できる参照実装は tests/consumer/read_sidecar.py にあります。
エージェントとの連携を2行で示した例については docs/ai-integration.md を、各フィールドを詳しく解説した内容については docs/feedback-schema.md をご覧ください。
CI:2 行のリグレッションゲート
GitHub Actions をお使いですか?.github/actions/clickcast には、このレシピ(および以下のビジュアル diff ゲート、ブラウザーのキャッシュ、リールとサマリーテーブルを含む PR コメント)が再利用可能な Action としてパッケージされています。詳しくは docs/ci/README.md をご覧ください。このセクションは、他のすべての CI プラットフォーム向けの標準レシピであり、シェルの 2 行のためにサードパーティの 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())はピクセルレベルの補完機能です。2 つのサイドカーのステップを対応付けてフレームのピクセル差分を取り、各ステップの変更ピクセル率と、変更された領域のリストに加えて、領域をハイライトした差分画像を出力します。「フローが壊れた」(ステップ数が違う、ステップが失敗するようになった)ことを検出するには assertions を使い、「フローは正常に動作したが、ボタンが移動した/色が変わった/レイアウトがずれた」ことを検出するには diff を使います。両方を組み合わせ、CI で実行すれば全体を網羅できます。ピクセルの差異だけが気になる場合は、diff だけを実行してください。
clickcast diff reel.gif.json tests/golden-tour.gif.json \
--out diff-report --fail-above 5
いずれかのステップの変更ピクセル率が --fail-above を超えた場合、またはベースラインの対応するステップとペアにできなかった場合(ステップ数が一致しない場合はラベルによる照合に切り替え、それでも対応しないものは黙ってスキップせず、フラグを立てます)に、ゼロ以外の終了コードを返します。--out を指定すると、領域をハイライトした差分画像と、CI アーティファクト用の summary.json が保存されます。--threshold はピクセルごとのノイズ閾値を調整します。Clickcast 独自のオーバーレイ(プログレスバー、アクションラベル、アクションパネル、カーソルとリップル)は、デフォルトで差分の対象から除外されます。除外しないと、実行のたびに独自の UI がリグレッションとして検出されるためです。厳密な生ピクセル差分を行う場合は、--no-exclude-overlays を指定してください。Python でも reel.visual_diff(run_path, baseline_path) を使って同じシグナルを取得できます。
設定
優先順位(高い順):
- CLI フラグ
- シナリオの
meta:ブロック CLICKCAST_*環境変数- プロジェクトの
./clickcast.toml - ユーザー TOML(パスは
clickcast config pathで確認) - 組み込みのデフォルト値
すべての 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
出力形式
| 形式 | 最適な用途 | 備考 |
|---|---|---|
gif | README、チャット、手軽な共有 | 互換性が最も高く、ファイルサイズは大きめです。 |
mp4 | ドキュメントサイト、ソーシャルメディア、長めのツアー | 長さに対するファイルサイズが最小です。imageio-ffmpeg に同梱されたバイナリを使用します。 |
webp | Web への埋め込み | サイズと品質に優れ、アニメーションにも対応しています。 |
frames | カスタムパイプライン | 連番付きの PNG と frames.json マニフェストを出力します。 |
--quality 1..30 は、ファイルサイズと忠実度のバランスを調整します(値が小さいほど高品質です)。--loop 0 は無限ループし、--loop 1 は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)
- Session は、指定されたビューポート/デバイスで Playwright ブラウザーを起動します。
- Actions は、正規化されたタイミングとカーソル追跡を用いて、各ステップを1つずつ実行します(
click、type、scroll、…)。 - Recorder は、各ステップの事前フレームと N 個のパディングフレームをキャプチャします(ファイル名は決定的で、パディング用フレームはバイト単位で同一のコピーです)。
- PageStateCollector は、サイドカー用にページイベントを購読します。
- Encoder が最終成果物を生成し、ReportBuilder が JSON を仕上げます。
アノテーター(clickcast.annotate.Annotator — クリックの波紋、カーソルの軌跡、キャプションバー、進捗バー)は、v0.1 ではライブラリ API として提供されます。auto/run の出力への自動組み込みは v0.2 で予定されています(ロードマップを参照)。
トラブルシューティング
- 空白のフレーム — サイトが SPA です。
--initial-waitを増やすか、最初のステップにwait: networkidle(または特定のセレクター)を追加してください。 ffmpeg not found—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を参照)では、v1 の利用側に影響を与えずにgraphブロックを追加する予定です。
コントリビューション
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) · 設定の優先順位 · フィクスチャ用テストサイト · ドキュメント。
v0.2(予定 — #29で追跡中):
- フレーム上の HUD — ステップインデックス、アクションの動詞、対象のロール、URL を表示する固定ヘッダー/フッター。LLM が画像のリールを並べて「読める」よう、OCR で判読できる形式にします。
- BFS による UI 探索 —
clickcast explore <url>はアプリを状態グラフとして扱い、発見 → クリック → 新しい状態を発見 → 再帰的に探索します。範囲を制限でき、決定的に動作し、訪問済み状態の重複を排除します。 - サイドカーのスキーマ v2 — トップレベルに
graphブロックを追加します(ノード = 個別のページ状態、エッジ =(from, to, action, transition_kind))。 auto/runの出力への自動アノテーション。
関連プロジェクト
vercel-labs/webreel — 洗練されたデモ動画を作成するための TypeScript ツールです。名前が似ており、出力も重なるため混同されやすいので、違いを説明します。clickcast は主に、ライブ Web UI を視覚的なモダリティとして必要とする AI エージェント を対象とした Python ツールであり、再現可能なデモリールを作成したい人間も対象としています。手作業でマーケティング動画を作成したい場合は、webreel のほうが適しています。
ライセンス
MIT © 2026 Alex Kay。LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。