リポジトリウォークスルービデオ は何をしますか?
目標は、チームメイトが見てリポジトリを理解できるビデオを作成することです。リポジトリの目的、各部分の連携、すべての関数の実際の動作、そして現在壊れているものを含めます。この中には2つのジョブが混ざっており、以下の順序で行う必要があります。
- リポジトリを実際にテストする。 ビデオに表示されるすべてのコマンドは実際に実行され、その出力が読まれます。
- ストーリーとして録画する。 チャプターはシステムの構造に従い、それぞれにナレーションが付きます。
成功するコマンドだけを表示するビデオはチームを誤解させます。テスト中に見つけた失敗は、多くの場合ビデオの最も価値のある部分なので、独自のクロージングチャプターを割り当ててください。
出力レイアウト
リポジトリの外側のフォルダで作業します。ユーザーが選択します。選択しない場合は、<repoの親>/video/ のような兄弟フォルダを使用します。なぜなら、/video のようなディスクルートパスはmacOSでしばしば読み取り専用だからです。
video/
├── <name>-walkthrough.mp4 # 完全なビデオ: チャプター + mov_text字幕トラック
├── <name>-walkthrough.srt # 同じナレーション、トランスクリプトとしても使用可能
├── chapters/NN-slug.mp4 # チャプターごとに1ファイル
├── README.md # 開始時刻付きチャプターインデックス、再録画方法
├── src/ # engine.py, make_readme.py, script.py (+ ヘルパー)
├── work/ # 使い捨てのリポジトリクローン: すべてのコマンドがここで実行される
└── build/ # 中間ファイル(セグメントごとの音声、フレーム、クリップ)
デモコマンドをユーザーの作業コピーで実行しないでください。work/ にクローンします(git clone <repo> work/<name>)。これにより、ビデオは意図的にものを壊し(不良マニフェスト、注入された障害)、git checkout . && git clean -fd でリセットできます。ユーザーのチェックアウトに未コミットの変更がある場合は、それについて言及し、そのままにしておいてください。
ステップ1: ツールを確認し、不足しているものをユーザーに伝える
which vhs ffmpeg ffprobe jq; python3 -c "import PIL; print(PIL.__version__)"; say -v '?' | head -3
何か不足している場合は、インストールする前にユーザーに何をインストールすべきか、その理由を伝えてください(brew install vhs ffmpeg jq)。Pillowについては、システムPythonに触れないでください。代わりにuvを使用してエンジンを実行します: uv run --no-project --with pillow python engine.py ...。これをシェル関数でラップします(py() { uv run --no-project --with pillow python "$@"; })。なぜなら、コマンドを保持する変数は1つとして展開されないからです。リポジトリが必要とするもの(Dockerの実行、シミュレータースタック、認証情報など)にも同じことが言えます。それらについてはユーザーに尋ね、決して秘密を作成しないでください。プレミアム音声(システム設定 → アクセシビリティ → 読み上げコンテンツ、例: "Ava (Premium)")はデフォルトの Samantha よりもはるかに聞こえが良いです。それを提案しますが、必須にしないでください。VOICE=... engine.py --force で後で音声を変更できます。
ステップ2: ナレーションを一言も書く前にリポジトリを理解してテストする
README、ドキュメントやADR、CLIエントリポイント(すべてのサブコマンドの --help)、テストマーカー、Makefile、CI設定を読んでください。ユーザーが実行できるすべての関数のインベントリを作成します: 各CLIサブコマンド、各テストスイート、各統合、コードが防御する各障害モード。
次に、それらすべてを work/ で実行し、以下を書き留めます:
- 各機能を適切に表示する正確なコマンド(短い出力。
jq、head、tail、cut -c1-160でパイプする) - 何が失敗し、それが本当のバグなのか、環境の問題(デフォルトパスの誤り、環境変数の欠如)なのか。クローン内または環境変数で環境問題を修正し、その修正をビデオで可視化します。なぜなら、チームもそれに遭遇するからです。
- 各安全ルールを意図的に破る方法(フィクスチャ、コピーへの
sed)。これにより、ビデオでルールが作動する様子を表示できます。
これらのメモは発見チャプターになります。番号付きの具体的な項目のリストとして保持してください。
ステップ3: チャプターを計画する
フォルダ一覧ではなく、システム独自のパイプラインに従ってください。うまくいった形状:
| # | チャプター | 内容 |
|---|---|---|
| 00 | ようこそ | タイトルカード、次に「これから見るもの」スライド |
| 01 | 全体像 | 一文の目的、パイプラインを箱と矢印で、リポジトリレイアウトのターミナルシーン |
| 02 | セットアップ | インストール、目的別にグループ化されたCLI、高速テストスイート |
| … | パイプラインステージごとに1チャプター | 実際のコマンド、さらにルールごとに「意図的に壊す」シーン |
| … | ライブ/統合 | 実際のバッキングサービス、エンドツーエンド |
| N-1 | 契約/引き継ぎ | 他のチームが依存しているもの |
| N | 発見と次のステップ | 番号付き発見リスト、次に何をすべきか |
チャプターあたり1〜3分、合計15〜25分を目指してください。チャプターは1つのアイデアです。セグメントは1つの画面と1つのナレーションです。録画前にこの概要(チャプタータイトルとそれぞれ1行)をユーザーに見せてください。
ステップ4: src/script.py を書く
バンドルされたスクリプトをビデオフォルダにコピーします:
mkdir -p video/src && cp <skill-dir>/scripts/{engine.py,make_readme.py,agent.jq} video/src/
cp <skill-dir>/scripts/script_template.py video/src/script.py
script.py はすべての言葉とすべてのコマンドを保持します。engine.py はそれをビデオに変換します。references/script-format.md を読んで、完全なセグメントスキーマ、スライドレイアウト、ナレーションスタイルを確認してください。scripts/script_template.py は各セグメントタイプを作業例で示しています。残りのチャプターを同じ形状で構築します(ステップ3がチャプター概要を示します)。
最も重要なナレーションルール:
- 耳で聞くために書く: 短い文、マークダウンなし、音声が誤って発音する頭字語はスペルアウトする(
"M C P"、"C L I")、またはscript.pyのSPOKENに追加する。 - 視聴者が何を見るべきかを言う(「スキルを見てください: ゼロ」)。音声と画像は一致しなければならないので、コマンドの出力(カウント、速度係数)を変更した場合は、文も修正してください。
- キャプション(ターミナルシーンの下部バー)は要点を述べる1行で、
コードをバッククォートで囲みます。
ステップ5: ドライラン、そして録画
cd video/src # `py` = Pillow付きPython(ステップ1参照)
py engine.py --dry # すべてのターミナルコマンドをプレーンbashで実行し、出力を表示、ビデオは生成しない
py engine.py --dry --only 04 # 1チャプターのみ
py engine.py --only 04 # 1チャプターを録画(見た目の迅速なフィードバック)
py engine.py # 欠落または変更されたものすべて、次に完全なビデオを組み立てる
py engine.py --only 07 --reuse-terms # VHSクリップを保持し、音声とフレームのみを再作成(ナレーション修正)
py make_readme.py # チャプターインデックス付きのREADME.mdを書き込む
常に最初にドライランを行ってください。1時間ではなく数分で済み、エラー、ハング、または過剰な出力を引き起こすすべてのコマンドをキャッチします。最初に1チャプターを録画し、完全なビルドの前にフレームを確認してください:
ffmpeg -v error -ss 20 -i chapters/04-*.mp4 -frames:v 1 build/check.png # 次にPNGを読む
完全なビルドには長い時間がかかります(21分のビデオで約40分)。バックグラウンドで実行し、ポーリングではなく完了通知を待ちます。チャプターはスクリプトのハッシュによってキャッシュされるため、再実行は変更されたものだけを再構築します。
ステップ6: 確認と引き渡し
ffprobe -v error -show_chapters -show_streams -of compact video/<name>-walkthrough.mp4 | head -40
以下を確認してください:
- 再生時間
- 1920×1080 h264、aac、mov_text字幕ストリーム
- チャプターごとに1つのチャプターマーカー
- いくつかのチャプターからのサンプルフレーム: テキストがボックスからはみ出していない、キャプションが2行以内
次に、MP4、chapters/ フォルダ、SRT、READMEの正確なパスをユーザーに伝えてください。開き方(open video/<name>-walkthrough.mp4; QuickTimeまたはVLCでチャプターと字幕メニューが表示されます)と発見リストを追加してください。実行中のままにしたコンテナやサービスがあれば言及し、その停止方法を伝えてください。
すでに解決されている落とし穴(エンジンを編集する際に覚えておいてください)
- サンドボックス化されたシェル: vhs、Docker、
uvキャッシュ、sayはしばしばコマンドサンドボックス下で失敗します(「Operation not permitted」、Dockerソケットエラー)。これらのコマンドはサンドボックスの外で実行する必要があります。openもブロックされるため、ユーザーが自分で実行するコマンドを提供してください。 - VHSフレームドロップ: デフォルトの50 fpsは長いシーンでフレームをドロップします。エンジンは
Set Framerate 15を使用します。 - VHSの
Outputは裸のファイル名でなければなりません。cwdを出力フォルダに設定してvhsを実行してください。 - VHS文字列にはエスケープがありません。
json.dumpsの引用はPS1エスケープシーケンスを壊します。エンジンでq()を使用してください。これはテキストに含まれない"、'、または`デリミタを選択します。 Waitは パターンがプロンプトと一致しない場合にハングします。エンジンは$で終わるPS1を設定し、WaitPattern /[>$]$/を使用します。$または>で終わる最終行を出力するコマンドは待機を早期に終了させる可能性があるため、そこにpauseを追加してください。- 長時間実行されるシーン(AIエージェント、パイプライン実行): セグメントに
"speedup": Trueを設定してください。エンジンはクリップをナレーションの長さにほぼ等しく高速化し、ヘッダーにsped up ×N.Nをスタンプするため、高速化されていることを述べてください。 - スライド上のテキストオーバーフロー:
wrap()は等幅フォントでコードスパンを測定します。ボックス本文は短く保ち、長いパスは2行に分割してください。 - 待機ループ:
pgrep -f <pattern>ループはそれ自体と一致します。代わりにPIDまたはファイルを待機してください。 - Beforeフック(チャプターの
"before": [...])は状態を準備します: DBコンテナのリセット、パイプラインのトリガー、障害の注入。元に戻す(リセット、注入解除)を同じチャプターに入れてください。これにより、1つのチャプターの再ビルドがプラットフォームを壊したままになることはありません。 - デモに必要なシークレットは、クローン内のgit無視ファイル(例:
dev-vault.env)に入れてください。その値を画面に表示したり、コミットしたりしないでください。
AIエージェントの動作表示(オプション)
リポジトリがエージェントを構築または設定する場合、最も強力なシーンはエージェントが実際の注入された障害を診断する場面です。ヘッドレスでストリームJSON出力を使用して実行し、バンドルされた agent.jq でストリームをフォーマットします(ツールコールごとに1行、次に回答):
claude -p "<質問>" --output-format stream-json --verbose | jq -rj -f /path/to/video/src/agent.jq
そのセグメントを "speedup": True とマークし、同じチャプター内で後で障害をリセットしてください。