1仕組みと動作原理
中核となるのは「短編全体を1つの自己完結型HTMLに集約する」点です。画面の全ピクセルをコードで計算し、画像、フォントファイル、外部ライブラリを一切排除します。ヘッドレスブラウザでフレームごとにシークしてMP4化し、「各フレームはフレーム番号の純粋関数である」という前提から再現性を確保します。
Make short animated films where every pixel is computed: no images, no fonts to load, no libraries. One HTML file holds the whole piece; a headless browser seeks it frame by frame into an MP4.
デフォルトのワークフローは意図的に「途中で質問して停止しない」設計です。形式・尺・アスペクト比を推論した後は一気に処理を完走させ、納品時に修正可能な項目を提示します。完全にテーマが存在しない場合にのみ事前に質問します。
Run straight through. Pick sensible defaults and mention alternatives at delivery. Ask *before* starting only if there is no subject at all (e.g. "make an animation", nothing else).
映像と音声は同一データによって駆動されます。ビートグリッド、絵コンテ表、ステージングをページ内のBPM/SECTIONS/SHOTS/EVENTSとして事前定義し、シーン、カメラ、BGMが同時にこれを読み取ることで、構造的な音画同期を実現します。
These go into the page as `BPM`, `SECTIONS`, `SHOTS`, `EVENTS`: the scenes, camera and soundtrack all read them, so picture and sound line up by construction.
描画ルールは手描きアニメーション特有の失敗パターンを防止します。純粋なフレーム番号関数(rAF状態/CSSアニメーション/累積物理演算の禁止)、毎フレームではなく4フレームごとにシードを変更するラインボイル(線の揺らぎ)、楕円や角丸長方形を用いた身体造形、ポーズが最も認識しやすいアングルからの構図取り、前後描画順の明示的な規定を徹底します。
- **Boil, don't jitter.** Change the wobble seed every 4 frames (`BOIL`), not every frame. Every frame reads as noise; ~7.5 changes a second reads as hand-drawn.
自動チェックはスクリプトによる関門と2回の人手目視を組み合わせます。まずasset-audit / layout-check / sync-checkを実行し、その後に絵コンテ準拠確認(storyboard conformance)とディレクターパス(2fpsのコンタクトシート採点)を実施します。
Scripts first: `asset-audit` CLEAN, `layout-check` CLEAN, `sync-check` passing (a remaining STARTLE is acceptable only on a deliberate stinger you can name). Then the two passes by eye below.
テキストの重なりは目視ではなくツールで判定します。starterのclaim()/placeFree()で各テキスト枠と主要オブジェクトのバウンディングボックスを登録し、layout-checkがサンプリングされたフレームごとに重なりとその発生時刻を検出・報告します。
- **Text never collides.** Claim every text box and key object; `layout-check` must print CLEAN. A caption overlapping a monitor edge or a face looks careless, and eyes on a contact sheet miss it.
人物写真は「ローカルでの参照」のみに制限されます。特徴抽出手法を用いて被写体をスタイル化されたキャラクターとして描き、アップロード、埋め込み、配布物への混入を明示的に禁止します。これは本スキルの唯一のプライバシー条項であり、厳格な制約事項です。
Photos stay local: never upload them or put them in anything published.
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| package | playwright-core(脚本用它启动 Chrome 逐帧 seek 页面);另需 Chrome 或 `npx playwright install chromium` |
| cli | ffmpeg(jpeg 管道编码 H.264、拼接触表、把离线渲染的 WAV 混进 MP4) |
| cli | 兄弟 skill 的同步检查:node ../soundtrack/scripts/sync-check.mjs(跨 skill 调用其 ffmpeg/ffprobe 分析) |
| network | 无执行期外部端点:交付页面的契约就是「不加载任何东西」,由 asset-audit 的静态规则 + 实跑网络记录双向证明 |
| package | Web Audio(浏览器内置的 OfflineAudioContext,用于离线渲染页面内合成的配乐;由 soundtrack 模板提供) |
4推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: node scripts/render.mjs piece.html sheet.jpg --sheet 1 / --stills 90,300,61
- 网络端点: 外部ネットワークアクセスの宣言: 本スキルのスクリプト自体は業務リクエストを送信しません。Playwrightはローカルのfile://ページを開き、ffmpeg/ffprobeはローカルファイルのみを読み込みます
- 本地工作目录: ファイルの読み書きと成果物出力: <out>.mp4(動画本編)、<out>-<frame>.jpg(静止画)、outで指定されたファイル名のコンタクトシート画像(render.mjs)
5二重目の独立検証
- [ok] 脚本是否真的无网络外发(蓝档的关键) — 三个 .mjs 逐个读过:render.mjs 只 spawn ffmpeg 与 playwright 打开 file:// 页面;asset-audit.mjs 的 live check 只监听请求并打印;layout-check.mjs 只 evaluate window.draw/LAYOUT。skill 目录内无 fetch/http 调用点。
- [ok] 是否有凭证/环境变量读取 — `process.env|API_KEY|TOKEN|SECRET|Authorization` 在本仓命中仅一处:skills/soundtrack/references/ai-music.md 的 $OPENROUTER_API_KEY(属 soundtrack)。本 skill 内零命中,credential_reads 为空成立。
- [ok] 是否有更高的触发条件被漏掉(红档特征) — `sandbox|automationcontrolled|no-verify|stealth|bypass|dangerously` 全仓零命中;浏览器以默认方式启动(`chromium.launch({ channel: 'chrome' })`,无 stealth 补丁、无关 TLS/沙箱开关)。
- [ok] SKILL.md 引用的脚本与模板是否都真实存在(有无示意命令) — 四条命令逐条核对到真实文件:scripts/render.mjs、scripts/asset-audit.mjs、scripts/layout-check.mjs、templates/starter.html 均在 skill 目录内;跨 skill 的 ../soundtrack/scripts/sync-check.mjs 在同仓兄弟 skill 目录内存在。无空引用。
- [ok] 「zero-asset」是否是可执行契约而非口号 — asset-audit.mjs 有 13 条静态规则(含 data: URI、@font-face、动态 import、base64 大块)与一次实跑网络记录,命中即 exit 1;qc.md 把 'asset-audit CLEAN' 列为交付前第一道门禁。契约可执行。
- [ok] 「照片只本地」的隐私声明是否两处一致且可定位 — SKILL.md 触发条件表内 'Photos stay local: never upload them or put them in anything published.';character.md 第 6 步 'Photos are for looking at locally. Never upload them, embed them, or put them in anything published.' 两处同口径,无矛盾。
- [ok] 「每帧是帧号的纯函数」是否与 starter/render 实现相符 — starter.html 顶部注释写死契约(不许 Math.random/Date,用 rng(seed)/hash2,任意帧可单独渲染),render.mjs 只调用 window.draw(f) 取 dataURL、不做时间推进;两侧一致,声明属实。
6結論
cf575d5199b6a4ed…