本文へスキップ

Komadori ​

1080p で 10 秒、100 万ボイドのクリップが、11-14 秒でできます。 ターミナルからは canvas が動くところを見られず、あなたのエージェントも同じです。Komadori はページを 1 フレームずつ動かし、描かれたものを返します。クリップ、コンタクトシート、レポートです。

spryte のデモの 100 万ボイドを、Komadori のクリップにしたものです。1080p の 10 秒を 11-14 秒で作れました。このファイルは 720p です。

その実行のコンタクトシート。サンプルした 20 フレームを 1 枚にまとめた画像

同じ実行のコンタクトシートです。サンプルした 20 フレームを 1 枚にまとめ、レポートと並べて書き出します。

失敗したゴールデンフレーム。保存したフレーム、星の色を変えた新しいフレーム、その差分

失敗したゴールデンフレームです。保存したフレーム、星の色を変えた新しいフレーム、その差分を並べています。ピクセルの 16% が変わりました。

コマ撮り(Komadori)は stop-motion のことです。Komadori はあなたのページを Chrome で動かし、1 フレームずつ進めて、コンタクトシート(サンプルしたフレームを 1 枚にまとめた画像)とレポートを書き出します。--mp4 を付けると、クリップも書き出します。spryte のシーンのために作りましたが、canvas に描くページならどれでも使えます。

sh
npx komadori dist --frames 600 --size 1920x1080 --out render --mp4 render/clip.mp4

dist はビルド済みのフォルダか URL です。Komadori には Node 20、Chrome または Chromium が必要で、--mp4 を使うなら ffmpeg も必要です。

ページにフレーム関数を用意する ​

Komadori は window.__frame() という 1 つの関数でページを進めます。この関数は、シーンをちょうど 1 フレーム進めて描画します。通常のループは人間用に残し、ステップ実行のモードをクエリ文字列の後ろに足します。

ts
if (new URLSearchParams(location.search).has("capture")) {
  window.__frame = () => {
    step(1 / 60);
    render();
  };
}
sh
npx komadori dist --query "capture=1" --frames 600

ステップは 1/60 秒に固定してください。そうすると、マシンの速さに関係なく、クリップは意図した速さで再生されます。乱数もシードを固定すると、2 回の実行で同じフレームになります。spryte の100 万ボイドのデモが実際に動く例です。

何を検査するか ​

次のとき、実行は終了コード 1 で失敗します。

  • ページがエラーを投げた、またはリクエストが失敗した
  • シェーダーがコンパイルできない
  • サンプルしたフレームがすべて単色、またはフレームがほとんど変わらない

シェーダーのエラーには、シェーダーのソースの行番号、コンパイラーのメッセージ、その行の内容が付きます。

内容がフレームの端に触れていて、切れているかもしれないときは警告します。終了コード 2 は、レンダリング自体ができなかったことを表します。たとえば、ページが window.__frame() を定義していない場合です。

縞模様、読みにくい文字、好みでない色は検出できません。contact-sheet.png を開いて見てください。--keep-frames dir を付けると、サンプルしたフレームを実寸で保存します。

クリップ ​

--mp4 は、フレームごとにページ全体のスクリーンショットを撮ります。--capture canvas は、代わりにページの中で canvas をエンコードするので、約 3 倍(実行によって 2.6-3.6 倍)速くなります。spryte の100 万ボイドのデモの 10 秒、1080p のクリップは、Chrome(Windows)で Radeon 780M でも RTX 5060 のノート PC でも 11-14 秒でした。

sh
npx komadori dist --query "capture=1" --frames 600 --size 1920x1080 --mp4 clip.mp4 --capture canvas

クリップに入るのは canvas だけなので、上に HTML で描いたタイトルやロゴは写りません。指定したサイズで Chrome が H.264 をエンコードできないときは、Komadori は止まってその旨を伝えます。

ゴールデンフレーム ​

ゴールデンフレームは、シーンがこう見えるべきという姿を保存した画像です。以降の実行では、フレームが一致しなくなると失敗します。

sh
npx komadori approve dist --frames 120 --samples 5 --size 1280x720 --golden golden
npx komadori dist --frames 120 --samples 5 --size 1280x720 --golden golden

approve はシーンを 2 回レンダリングし、2 回が一致したときだけフレームを保存します。失敗したフレームは、番号、変化したピクセルの割合、領域とともに報告されます。Komadori は、ゴールデンフレームと新しいフレームと差分を並べた画像も書き出します。--yes を付けない限り、approve は既存のゴールデンフレームを置き換えません。

同じレンダラーでは、フレームの 0.01% のピクセルまでの違いは許容されます。別のレンダラーで作ったゴールデンフレームは 0.25% の上限で比較され、警告が出ます。この上限は、Radeon 780M、RTX 5060 のノート PC、Vulkan SwiftShader での測定から決めました。測定値はゴールデンフレームのメモにあります。spryte の CI は、ショーケースのシーンにこれを使っています。

エージェント向け:MCP サーバー ​

komadori mcp は、Komadori を 3 つのツールを持つ MCP サーバーとして動かします。render は検査結果とコンタクトシートを返し、look は 1 フレームを実寸で、またはズームして返します。diff は、1 つ前のレンダリングの同じフレームと比べます。

json
{ "mcpServers": { "komadori": { "command": "npx", "args": ["-y", "komadori", "mcp"] } } }

できないこと ​

  • Chrome で動きます。Windows でテストしていて、ゴールデンフレームの検査は Linux のランナー(SwiftShader)でも動いています。
  • エージェントがこれを使うと良いシーンを書けるかどうかは、確かめられていません。4 つの小さなタスクでは、Sonnet はレンダリングなしでも同じ結果でした。実行と費用は評価のページにあります。
  • 検査するのは何が描かれたかであって、見た目が良いかどうかではありません。

ソースと変更履歴は GitHubに、パッケージは npm にあります。