show-n-tell は何をしますか?
あなたは、任意のWebサイト+ロゴ+少しの意図を、5分間のナレーション付きブランドデモ動画に変換する完全なパイプラインを統括します。scripts/ 内のスクリプトは単なるパイプであり、あなたが指揮者です。
このフォルダ内のリファレンスドキュメント: docs/SCHEMAS.md (YAML + アクション文法)、docs/GOTCHAS.md (既知の問題と回避策)、docs/CONTEXT.md (「良い出力とは何か」)、examples/halyard-spme/ (正規の完全な例)。必要に応じてこれらを読んでください — 事前にロードしないでください。
このスキルを使用するタイミング
- ユーザーがWebサイト(ライブ、ローカル開発環境、静的サイト)のナレーション付きデモ動画を希望している。
- ユーザーが少なくとも軽い意図のガイダンスを持っている(「X、Y、Zを表示」/「ダッシュボードフローをデモ」)。
- ユーザーがロゴまたはワードマークにアクセスできる。
ユーザーが意図メモもロゴも提供しない場合は、処理を拒否してください。 デフォルトのブランディングによる汎用的なデモは質の低いデモです。黙って質の低い動画を生成するのではなく、ガイダンスを求めてください。
環境検出(開始前にお読みください)
何をする前に、Claudeがどの環境で実行されているかを判断してください。
- Cowork:
mcp__cowork__list_artifactsとmcp__computer-use__screenshotがClaudeのツールリストに存在します。 - Claude Code CLI: これらのツールは存在しません。
これは、いくつかのフェーズで環境によって動作が異なるため重要です。クイックリファレンス:
| フェーズ | Claude Code CLI | Cowork |
|---|---|---|
| 作業ディレクトリ (フェーズ 5) | ~/demo-videos/<スラッグ>/ | request_cowork_directory がパスを出力 |
| サイト探索 公開 (フェーズ 2b) | Playwright MCPツール | Chrome MCPツールまたは explore_page.py ヘッドレス |
| 認証情報取得 OAuth (フェーズ 2a) | capture_auth.py を Bash経由で実行 | ユーザーがローカルで capture_auth.py を実行 |
| 長時間コマンド (フェーズ 7–9) | 同期的に実行 | nohup + ポーリング (45秒のbashタイムアウト) |
| 引き継ぎ (フェーズ 11) | mp4パスを報告 | mp4パス + computer://リンク |
フェーズ 1 — インタビュー(入力収集)
一度にすべてを尋ねるのではなく、1~2の質問を一度に行ってください。必須:
- ターゲットURL — 到達可能であることを確認します。
- デモ意図メモ — 何を伝えるストーリーですか? どの機能が重要ですか?
- オーディエンス + トーン — 社内/社外/投資家向け; 説明/営業/技術/カジュアル。
- 目標時間 — デフォルト5分。
- ロゴ — URLまたはパス。テキストのみしか利用できない場合は、その制限を伝えますが、受け入れます。
- ブランドカラー — プライマリ(インク)+ アクセント。指定がない場合は、PILを使用してロゴから推測します。
- 認証は? — サイトにログインが必要ですか?
- いいえ → 進みます。
- はい、フォームベース(管理可能な独自のメール/パスワードフィールドがあるサイト) →
demo_config.yamlでsession.pre_sessionを使用します。認証情報の環境変数名(実際の値ではない)とログインURL/セレクターを収集します。実際の認証情報は自分で<作業ディレクトリ>/.envに配置するようユーザーに伝え、チャットでは決して入力しないでください。examples/login-flow/を参照してください。 - はい、OAuth / SSO / マジックリンク / パスキー(Google、Microsoft、Oktaなど) →
session.storage_stateを使用します。ユーザーはコマンドを実行しません。あなたがフェーズ2aでhelpers/capture_auth.pyを起動し、ユーザーは開いたブラウザウィンドウで対話的にログインするだけです。キャプチャされたauth.jsonは、フェーズ2bの探索とフェーズ8の録画の両方で使用されます。examples/oauth-storage-state/を参照してください。
フェーズ 2a — 認証情報取得(OAuthのみ)
フェーズ1の質問7で「認証なし」または「フォームベース」と決着した場合は、このフェーズを完全にスキップします。OAuth / SSO / マジックリンク / パスキーの場合は、サイト探索の前に認証済みセッションを今すぐキャプチャします — フェーズ2bで認証済みページを表示するために必要です。
mkdir -p ~/demo-videos/<demo-slug>/
uv run helpers/capture_auth.py <login_or_start_url> \
--out ~/demo-videos/<demo-slug>/auth.json \
--viewport <recording.viewport from demo_config.yaml; default 1440x900>
これを timeout: 600000 (10分 — 最大値) でBashツール経由で実行します。スクリプトはヘッド付きChromiumウィンドウを開きます。ユーザーに平易な言葉で伝えます:
「ログインするためのブラウザウィンドウを開きます。ログインを完了し(Google、Microsoftなど、2FA対応)、録画を開始したいページに移動してからブラウザウィンドウを閉じてください。セッションを保存し、自動的に続行します。」
スクリプトは auth.json をモード0600でアトミックに書き込みます。ユーザーが10分以上かかる場合(まれですが、別室での電話ベースの2FAなどで可能性あり)、Bashのタイムアウトが発生します — 同じコマンドを再実行するだけです。
--viewport は demo_config.yaml の recording.viewport と一致する必要があります。一部のサイトはビューポートサイズをフィンガープリントします;不一致は録画時または探索時にキャプチャされたセッションを無効にする可能性があります。
PlaywrightのChromiumがまだインストールされていない場合(新しいスキルクローン)、スクリプトは実行可能なエラーを表示します。uv run --with playwright playwright install chromium を一度実行します。
Claude Code CLIで実行する場合: 上記の説明に従って capture_auth.py をBashで実行します。
Coworkで実行する場合: Claudeはcomputer-useとChromeツールを使用してこれを直接処理し、ユーザーはブラウザが開いたときにログインするだけで済みます。手順:
-
作業ディレクトリパスが既知であることを確認します。 フェーズ5がまだ実行されていない場合は、
mcp__cowork__request_cowork_directoryを今すぐ呼び出して出力パスを取得し、<作業ディレクトリ>を<出力パス>/<demo-slug>/に設定します。 -
ユーザーのデスクトップでChromeを開きます:
mcp__computer-use__open_application → "Google Chrome" (または "Chrome") -
ログインURLに移動します。 可能であればChrome MCPを優先します:
- Chrome拡張機能が接続されている場合:
mcp__Claude_in_Chrome__navigateを<login_or_start_url>に - Chrome拡張機能が接続されていない場合:
mcp__computer-use__*ツールを使用してアドレスバーをクリックし、URLを入力します
- Chrome拡張機能が接続されている場合:
-
ユーザーにログインするよう伝えます — 平易な言葉で:
「ログインページでChromeを開きました。ログインし(2FA、SSOなどを処理)、録画を開始するページに移動してください。完了したらお知らせください。」
-
待機して監視します。 約15秒ごとに
mcp__computer-use__screenshotでポーリングします。URLがログイン/認証ページではなくなり、ダッシュボードまたはアプリページが表示されたら続行します。 -
JavaScriptを介してセッション状態を抽出します。 このスニペットを
mcp__Claude_in_Chrome__javascript_toolで実行します:(() => { const cookies = document.cookie.split(';').map(c => { const [name, ...rest] = c.trim().split('='); return { name: name.trim(), value: rest.join('='), domain: location.hostname, path: '/', expires: -1, httpOnly: false, secure: location.protocol === 'https:', sameSite: 'Lax' }; }).filter(c => c.name); const ls = {}; for (let i = 0; i < localStorage.length; i++) { const k = localStorage.key(i); ls[k] = localStorage.getItem(k); } const ss = {}; for (let i = 0; i < sessionStorage.length; i++) { const k = sessionStorage.key(i); ss[k] = sessionStorage.getItem(k); } return JSON.stringify({ cookies, origins: [{ origin: location.origin, localStorage: Object.entries(ls).map(([n,v]) => ({name:n,value:v})), sessionStorage: Object.entries(ss).map(([n,v]) => ({name:n,value:v})) }] }, null, 2); })() -
結果を
<作業ディレクトリ>/auth.jsonに書き込みます Writeツールを使用します。これは有効なPlaywrightstorage_state形式です —helpers/explore_page.pyとrecord_demo.pyは両方ともbrowser.new_context(storage_state=...)を介してこれを消費します。 -
HttpOnly Cookieの注意点。 JavaScriptはHttpOnly Cookieを読み取ることができません — これらは意図的に
document.cookieからは見えません。サイトのセッショントークンがHttpOnlyのみの場合(古いRails/DjangoセッションCookieで一般的)、抽出された状態にはそれが欠落します。ユーザーに伝えます:「注: HttpOnlyとマークされたセッションCookieはJavaScriptからアクセスできないため、すべての認証トークンをキャプチャできなかった可能性があります。録画はキャプチャされたものを使用しようとします — フェーズ8でログインウォールに当たった場合は、ローカルで
capture_auth.pyを使用するフォールバックが可能です。」 その後続行します — 多くの最新サイト(Google、Microsoft、Okta)は、非HttpOnly CookieまたはlocalStorageにPlaywrightが機能するための十分な状態を保持しています。
フェーズ 2b — サイト探索
フェーズ2aが実行された場合(auth.jsonが存在する)、helpers/explore_page.py を使用して認証済みページを表示します — Playwright MCPはstorage_stateをロードできず、ログインウォールしか表示しません。認証なしのデモの場合、Playwright MCPで問題なく、よりインタラクティブです。以前と同様に使用します。
認証済みページの場合:
mkdir -p ~/demo-videos/<demo-slug>/_explore/
uv run helpers/explore_page.py https://target.example.com/dashboard \
--storage-state ~/demo-videos/<demo-slug>/auth.json \
--out-dir ~/demo-videos/<demo-slug>/_explore/
これにより、ページごとに3つのファイルが _explore/ に書き込まれます: <slug>.png (スクリーンショット)、<slug>.dom.html (セレクター選択用DOM)、<slug>.meta.json ({url_requested, final_url, title, status})。ReadツールでPNGを読み取ってページを確認します;DOMをgrepしてセレクターを見つけます。meta.jsonの final_url がログインページを指している場合、セッションの有効期限が切れています — フェーズ2aを再実行します。
公開ページの場合(任意のデモのランディングページ、マーケティングページ;認証なしのデモのすべて) — 以前と同様にPlaywright MCPツール(mcp__plugin_playwright_playwright__*)を使用します:
browser_navigateでターゲットURLに移動し、次にユーザーの意図が言及する2~5ページに移動します。browser_snapshotまたはbrowser_take_screenshotで各ページのレイアウトを確認します。browser_evaluateを使用してDOMを読み取り、安定したセレクターを取得します(可能な場合はnth-of-typeよりもセマンティックを優先します)。
Claude Code CLIで実行する場合: 上記の説明に従って mcp__plugin_playwright_playwright__* ツールを使用します。
Coworkで実行する場合: まずChromiumが