eva feature shot
出荷済み機能のスクリーンショット1枚+ツイート1つ。Remotion、音楽、編集、画像へのキャプション埋め込みは一切不要。製品UIそのものがアセットです。
リポジトリルートの screenshots/ ディレクトリ(すでにgitignore済み)に2つのファイルが生成されます:
| ファイル | 説明 |
|---|---|
<YYYY-MM-DD>-<slug>.png | 生の2560×1440ショット — 保持してください。再撮影不要のソースです |
<YYYY-MM-DD>-<slug>-framed.png | こちらを投稿してください — 3200×1800、ブランドフレーム付き |
フレーム版は、生ショットをEvaのブランドグラデーション上に配置し、角丸、Evaアイコン、"Eva"ワードマークを上部に重ねます。そのため、このショットはバグレポートのスクリーンショットではなく、プロダクトアナウンスとして読まれます。
譲れないデフォルト設定
-
1280レイアウト、2560×1440(16:9)でHDキャプチャ。 スクリプトは実際のChromeをdeviceScaleFactor 2で起動し、
scale:"device"でキャプチャします。アプリはネイティブの1280幅でレイアウトされます(要素サイズが読める)が、PNGは2倍のピクセル密度 — Retinaタイムラインでくっきり表示されます。16:9はXがタイムライン内でクロップせずに表示するアスペクト比です。フレーム版の出力は3200×1800 — これも16:9なので、フレームはタイムラインの表示領域を無駄にしません。agent-browserではこれができません: そのscreenshotはCSSピクセルでキャプチャしDPRを破棄するため、常に1280×720で出力されます。HDスクリプトを使用してください。 -
フルページは絶対に避ける。 密集したアプリのフルページショットは縦長の帯になり、タイムラインでサムネイルサイズで表示されます。1ビューポート、1アイデア。
-
撮影前に開発用オーバーレイを非表示にする。 react-scan と agentation はどちらもページ内に描画されます。
scripts/hd-shot.mjsが処理します — 手作りの連携ではなく、スクリプトを使用してください。 -
アプリの実際のテーマに合わせる。 ユーザーが実行しているもの(ダークモードの場合は
set media dark)に従います。写真のためにアプリのスタイルを変更しないでください。 -
機能が視覚的主題でなければならない。 混雑したページの隅にある200pxのパネルは失敗です。機能が支配的なビューに移動するか、それを含むサーフェス(モーダル、シート、詳細ペイン)を開いて、タイムラインサイズで読めるようにします。
サイドバーは自動的に折りたたまれます。
shot.sh(および単純なhd-shot.mjs --pathショット)は、キャプチャ前にナビレールを折りたたみます — 1280pxフレームの約250pxを消費し、その中に機能が含まれることはありません。サイドバー自体が機能である場合にのみ--no-collapseを渡します。--recipeを使用する場合、ctx.collapseSidebar(page)を自分で呼び出します(レシピは独自のステージングを管理します)。同じルールが、サーフェスに非表示方法がある場合の二次的なリストレール(レビューリスト、設定ナビ)にも適用されます。生のPNGで確認してください。無関係なナビ項目の列が残っている場合は、再撮影します。
-
フレームを追加するが、注釈は付けない。 必ずステップ6を実行します — グラデーション+ワードマークがハウススタイルです。特に指示がない限り、矢印、赤い丸、吹き出しテキスト、偽のブラウザクロームを絶対に追加しないでください。
-
絶対に送信しない。タイプのみ。 入力フィールドを埋め、ピッカーを開き、状態をステージングしてから撮影します。コンポーザーでEnterを押さない、送信矢印をクリックしない、作成、保存、実行、開始をしない。実際のセッションやエージェント実行を決して開始しないでください。たとえより良いショットのためであっても。送信するとユーザーの実際のワークスペースを変更し、実際の計算リソースを消費します。ステージングされた状態が、あなたが撮影しているものです。Enterは、フィールド自体にコミットするだけで他に何もしない場合(開いているピッカーから
@-メンションを受け入れる場合)にのみ許可されます — それだけであることを確信できない場合は、代わりにピッカー行をクリックしてください。 -
データが汚いなら、データを修正 — 回避のために再撮影しない。 デフォルト7は、アプリを操作して状態を生成することを防ぎますが、状態を書き込むことは防ぎません。実際の開発データがショットを失敗させる一般的な理由です:エラーウォール(「Failed to stop sandbox」×8)、
Untitled session行、中途半端にマイグレーションされたターン、機能に3つ必要なのに1つしかないリポジトリ。ショットのためにアプリ自身の開発データを編集する方が、たまたま見栄えの良いセッションを探すよりはるかに優れており、アプリのスタイルを変更するよりはるかに優れています(デフォルト4は依然として有効 — CSSではなくデータを変更してください)。開発デプロイメントに直接書き込みます:
npx convex runで実行する使い捨てのinternal/screenshotStaging.tsミューテーション、またはConvexダッシュボード。セッションに実際に読めるタイトルを付け、フレーム内のエラー/システムメッセージを削除し、機能が必要とする2行目、3行目をシードします。これに関するルール:
- 開発デプロイメントのみ。 書き込み前にターゲットを確認し(
npx convex env get CONVEX_URLまたは.env.localを読む)、ステージングミューテーションを本番に向けないでください。 - まず追加的で元に戻せる方法を優先。 実際の履歴を削除するよりも、タイトルのパッチ適用やデモ行の挿入を優先します。どうしても削除する必要がある場合は、まず行を確認し、何を削除したかを伝えてください。
- もっともらしく、具体的に捏造しない。 実際の作業のように読めるタイトルとプロンプト。メトリクス、顧客名、ツイートで事実として繰り返す数字を決して捏造しないでください。
- ショットが完了したらステージングミューテーションを削除 — マイグレーションと同じクリーンアップルール。
- 何を変更したかを、引き継ぎの際にユーザーに伝えてください。
- 開発デプロイメントのみ。 書き込み前にターゲットを確認し(
-
機密性。 ユーザー自身のリポジトリ
vvedantb/evaを使用します。クライアントリポジトリ(evalucom/carepulse、eprocurement)や、それらをリストする「Codebases」ホームは絶対に使用しないでください。フレーム内のdoc/task/sessionリストにクライアント名の項目がないか確認 — リストが汚れている場合は、クリーンなデモ行をステージングします。画面上の名前やメールに関する個人データの懸念を決して提起しないでください — Settings → Experimental に blur-PID トグルがあり、すべての[data-pii]要素をぼかすので、これはプロダクト側で処理されています。エラーパネルが環境変数名やプロジェクトIDを漏洩している場合はフラグを立ててください。
ワークフロー
-
出荷されたものを特定する。 ユーザーがどの機能かを言っていない場合は、質問してください — 一度だけ、アンケートではありません。
git log --oneline -15、git diff --stat、またはinternal/changelog/(最新の月のファイル)で通常は名前がわかります。 機能とそれを表示するURLが必要です。 -
アプリを起動する。 開発サーバーだけでOK — HDスクリプトは独自のChromeを起動し、エージェントユーザーとしてログイン(
/?agent=true)します。新しいコンテキストでdeviceScaleFactor 2を使用します。agent-browserで撮影する必要はありません。pnpm dev # リポジトリルートから → localhost:5173 -
撮影する。 単純なURLショットの場合、
shot.shがナビゲート、サイドバー折りたたみ、オーバーレイ非表示、2560×1440でキャプチャを行います:bash .claude/skills/eva-feature-screenshot/scripts/shot.sh /vvedantb/eva/web/sessions sessionsURLパス+スラッグ(+オプションの待機ミリ秒、+オプションの
--no-collapse)を受け取ります。ステージングされたショット(メニューを開く、プロンプトを入力してからキャプチャ)の場合は、
.mjsでexport async function stage(page, ctx)をエクスポートするレシピを作成し、hd-shot.mjsに渡します。レシピはナビゲーション、サイドバー折りたたみ、ステージングを担当します。ctxは{ BASE, hideOverlays, collapseSidebar, settle }を提供します。page.getByRole(...)(Playwright)ロケーターを使用します。正確なアクセシブルネームを見つけるには、まずagent-browserをインタラクティブに操作し、snapshot -i/read_pageを使用します。// recipe.mjs — モードピッカーを開き、プロンプトを入力した状態でステージング export async function stage(page, ctx) { await page.goto(`${ctx.BASE}/vvedantb/eva/web/sessions`, { waitUntil: "networkidle", }); await ctx.settle(3000); await ctx.collapseSidebar(page); await page.getByRole("textbox", { name: /Ask Eva/ }).click(); await page.keyboard.type("Redesign the sessions sidebar…"); await page.getByRole("button", { name: "Edit", exact: true }).click(); await ctx.settle(600); }node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug session-modes --recipe /abs/path/recipe.mjsクリーンで読みやすい入力をステージングしてください — 整頓されたデモタイトルは、実際の汚いものより優れています。絶対に送信しないでください(デフォルト7)。
-
PNGを読み返し、判断する。 ここで悪いショットを発見します:
- 機能が明らかな主題ですか、それともクロームに埋もれていますか?
- オーバーレイやツールバーが生き残っていませんか?スケルトン、スピナー、
—プレースホルダーがまだ画面に表示されていませんか?(待機ミリ秒を増やして再撮影) - 四辺すべて:ラベルが切れている、ボタンが半分しかレンダリングされていない、列が途切れている?
- デフォルト9に従って機密情報はありませんか?
- 空の状態:「kanbanタスク」を証明する空のボードは悪いショットです。データを投入するか、別のビューを選んでください。
フレームがデータのために失敗する場合 — エラーウォール、
Untitled session、機能に3つ必要なのに1行しかない — 運の良い画面を探す代わりに、開発データをステージングします(デフォルト8)。 -
フレームを追加する。
bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> "Eva"screenshots/<today>-<slug>-framed.png(3200×1800)を書き込みます。templates/frame.htmlを独自のChrome(deviceScaleFactor 2)でレンダリングします — ショットとは別のブラウザなので、後で復元する必要はありません。フレーム版PNGも読み返してください — グラデーションが隅でUIを洗い流していないか、ワードマークが切れていないかを確認します。3番目の引数で別のパスから生のPNGをフレーム化します。templates/frame.htmlは、このスキルのブランドカラーが存在する唯一の場所です。 -
ツイートを書く。
eva-tweetスキルを呼び出します — フック、オプションのポジショニングフラグメント、→機能リスト、オプションのクローズ。スクリーンショットが証拠を運ぶので、ツイートは画像を説明するのではなく、何が存在するようになったかを述べます。画像には一切言及しないでください。 -
引き継ぐ。 フレーム版ファイルパスをマークダウンリンクとして、ツイートをフェンスブロックで、さらにフレーム内で投稿前にユーザーが確認すべきものを提供します。
クイックリファレンス
| 必要な操作 | コマンド |
|---|---|
| URLを撮影(HD) | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <path> <slug> [settle-ms] |
| サイドバーをフレーム内に残す | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <path> <slug> <settle-ms> --no-collapse |
| ステージングショット(メニュー/タイピング) | node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug <slug> --recipe <abs.mjs> |
| フレームを追加(これを投稿) | bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> [title] [raw-png] |
| アクセシブルネームを探す | agent-browserをインタラクティブに操作し、その後 agent-browser snapshot -i |
| 空白/壊れたページをデバッグ | agent-browser console · agent-browser errors |
落とし穴
- HDはPlaywrightに存在し、agent-browserにはありません。 agent-browserの
screenshotはCSSピクセルでキャプチャしdevicePixelRatioを破棄するため、1280×720に制限されます。hd-shot.mjs/hd-frame.mjsは、グローバルなagent-browserインストールにバンドルされているplaywright-coreを使用します。PW_COREが別の場所にある場合は設定してください。どちらもchannel:"chrome"を起動するため、システムにChromeがインストールされている必要があります。 - スクリプトは自身でログインします
/?agent=true(ブール値;/?agentはzodのSearchParamErrorをスローします)で、新しいブラウザコンテキストで実行されます。撮影にagent-browserセッションは必要ありません。 - 開発用オーバーレイは3つのノードで、すべて
<html>にぶら下がり、<body>にはありません。#react-scan-rootだけを非表示にするのは不十分です:react-scanは、idもクラスもない生のhtml > canvasにコンポーネントのアウトラインとラベルを描画し、それがショットを台無しにします。hd-shot.mjsは、インラインのdisplay:none !importantで3つすべて(#react-scan-root、html > canvas、[data-agentation-root])を強制非表示にします。スタイルシートはインラインスタイルに負けるためです。 - ステージングショットは新しいブラウザで実行され、あなたが探索したブラウザではありません。 セレクタを見つけるためにagent-browserを使用しますが、レシピはPlaywright自身のコンテキストで最初からナビゲートおよびステージングし直します — すべてのステップをレシピに入れてください。CSSよりも
page.getByRole(...)を優先します。@e1のような参照はここには存在しません。 - 2枚以上の画像はポイントを希釈します。 Xは1枚の画像を全幅で表示します。2枚目は両方を半分のサイズにします。本当のbefore/afterの場合にのみ、複数枚を撮影してください。
video/public/captures/を再利用しないでください — これらは別の目的でフレーム化されたRemotionアセットです。