Communitygithub.com

vvedantb/eva

本番アプリからクリーンなHDスクリーンショットを1枚取得(Playwright、deviceScaleFactor 2、1280レイアウトを2560×1440でキャプチャ、開発用オーバーレイ非表示)し、それを添付するツイートを作成します。ユーザーが機能をスクリーンショットや画像で紹介・告知・投稿したいときに使用します。

eva とは?

このスキルは、本番アプリ「Eva」の機能を高画質スクリーンショット1枚とツイートで紹介するためのものです。Remotionや動画編集は不要で、製品UIそのものがアセットとなります。Playwrightを使用してdeviceScaleFactor 2で1280px幅のレイアウトを2560×1440のHD画像としてキャプチャし、さらにブランドフレーム(3200×1800、グラデーション背景、Evaアイコンとワードマーク付き)を追加します。対応プラットフォームはX/Twitterで、フレーム画像はタイムラインに最適化されています。ワークフローは、機能の特定、アプリ起動、スクリーンショット撮影、画像の確認、フレーム追加、ツイート作成、引き継ぎの7ステップで構成され、すべての操作はユーザーの実際のデータを変更せず、タイプのみで行います。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/vvedantb/eva/tree/HEAD/.claude/skills/eva-feature-screenshot

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

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"ワードマークを上部に重ねます。そのため、このショットはバグレポートのスクリーンショットではなく、プロダクトアナウンスとして読まれます。

譲れないデフォルト設定

  1. 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スクリプトを使用してください。

  2. フルページは絶対に避ける。 密集したアプリのフルページショットは縦長の帯になり、タイムラインでサムネイルサイズで表示されます。1ビューポート、1アイデア。

  3. 撮影前に開発用オーバーレイを非表示にする。 react-scan と agentation はどちらもページ内に描画されます。scripts/hd-shot.mjs が処理します — 手作りの連携ではなく、スクリプトを使用してください。

  4. アプリの実際のテーマに合わせる。 ユーザーが実行しているもの(ダークモードの場合は set media dark)に従います。写真のためにアプリのスタイルを変更しないでください。

  5. 機能が視覚的主題でなければならない。 混雑したページの隅にある200pxのパネルは失敗です。機能が支配的なビューに移動するか、それを含むサーフェス(モーダル、シート、詳細ペイン)を開いて、タイムラインサイズで読めるようにします。

    サイドバーは自動的に折りたたまれます。 shot.sh(および単純な hd-shot.mjs --path ショット)は、キャプチャ前にナビレールを折りたたみます — 1280pxフレームの約250pxを消費し、その中に機能が含まれることはありません。サイドバー自体が機能である場合にのみ --no-collapse を渡します。--recipe を使用する場合、ctx.collapseSidebar(page) を自分で呼び出します(レシピは独自のステージングを管理します)。

    同じルールが、サーフェスに非表示方法がある場合の二次的なリストレール(レビューリスト、設定ナビ)にも適用されます。生のPNGで確認してください。無関係なナビ項目の列が残っている場合は、再撮影します。

  6. フレームを追加するが、注釈は付けない。 必ずステップ6を実行します — グラデーション+ワードマークがハウススタイルです。特に指示がない限り、矢印、赤い丸、吹き出しテキスト、偽のブラウザクロームを絶対に追加しないでください。

  7. 絶対に送信しない。タイプのみ。 入力フィールドを埋め、ピッカーを開き、状態をステージングしてから撮影します。コンポーザーでEnterを押さない、送信矢印をクリックしない、作成、保存、実行、開始をしない。実際のセッションやエージェント実行を決して開始しないでください。たとえより良いショットのためであっても。送信するとユーザーの実際のワークスペースを変更し、実際の計算リソースを消費します。ステージングされた状態が、あなたが撮影しているものです。Enterは、フィールド自体にコミットするだけで他に何もしない場合(開いているピッカーから @-メンションを受け入れる場合)にのみ許可されます — それだけであることを確信できない場合は、代わりにピッカー行をクリックしてください。

  8. データが汚いなら、データを修正 — 回避のために再撮影しない。 デフォルト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 を読む)、ステージングミューテーションを本番に向けないでください。
    • まず追加的で元に戻せる方法を優先。 実際の履歴を削除するよりも、タイトルのパッチ適用やデモ行の挿入を優先します。どうしても削除する必要がある場合は、まず行を確認し、何を削除したかを伝えてください。
    • もっともらしく、具体的に捏造しない。 実際の作業のように読めるタイトルとプロンプト。メトリクス、顧客名、ツイートで事実として繰り返す数字を決して捏造しないでください。
    • ショットが完了したらステージングミューテーションを削除 — マイグレーションと同じクリーンアップルール。
    • 何を変更したかを、引き継ぎの際にユーザーに伝えてください。
  9. 機密性。 ユーザー自身のリポジトリ vvedantb/eva を使用します。クライアントリポジトリ(evalucom/carepulse、eprocurement)や、それらをリストする「Codebases」ホームは絶対に使用しないでください。フレーム内のdoc/task/sessionリストにクライアント名の項目がないか確認 — リストが汚れている場合は、クリーンなデモ行をステージングします。画面上の名前やメールに関する個人データの懸念を決して提起しないでください — Settings → Experimental に blur-PID トグルがあり、すべての [data-pii] 要素をぼかすので、これはプロダクト側で処理されています。エラーパネルが環境変数名やプロジェクトIDを漏洩している場合はフラグを立ててください。

ワークフロー

  1. 出荷されたものを特定する。 ユーザーがどの機能かを言っていない場合は、質問してください — 一度だけ、アンケートではありません。git log --oneline -15、git diff --stat、または internal/changelog/(最新の月のファイル)で通常は名前がわかります。 機能とそれを表示するURLが必要です。

  2. アプリを起動する。 開発サーバーだけでOK — HDスクリプトは独自のChromeを起動し、エージェントユーザーとしてログイン(/?agent=true)します。新しいコンテキストでdeviceScaleFactor 2を使用します。agent-browserで撮影する必要はありません。

    pnpm dev   # リポジトリルートから → localhost:5173
    
  3. 撮影する。 単純なURLショットの場合、shot.sh がナビゲート、サイドバー折りたたみ、オーバーレイ非表示、2560×1440でキャプチャを行います:

    bash .claude/skills/eva-feature-screenshot/scripts/shot.sh /vvedantb/eva/web/sessions sessions
    

    URLパス+スラッグ(+オプションの待機ミリ秒、+オプションの --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)。

  4. PNGを読み返し、判断する。 ここで悪いショットを発見します:

    • 機能が明らかな主題ですか、それともクロームに埋もれていますか?
    • オーバーレイやツールバーが生き残っていませんか?スケルトン、スピナー、— プレースホルダーがまだ画面に表示されていませんか?(待機ミリ秒を増やして再撮影)
    • 四辺すべて:ラベルが切れている、ボタンが半分しかレンダリングされていない、列が途切れている?
    • デフォルト9に従って機密情報はありませんか?
    • 空の状態:「kanbanタスク」を証明する空のボードは悪いショットです。データを投入するか、別のビューを選んでください。

    フレームがデータのために失敗する場合 — エラーウォール、Untitled session、機能に3つ必要なのに1行しかない — 運の良い画面を探す代わりに、開発データをステージングします(デフォルト8)。

  5. フレームを追加する。

    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 は、このスキルのブランドカラーが存在する唯一の場所です。

  6. ツイートを書く。 eva-tweet スキルを呼び出します — フック、オプションのポジショニングフラグメント、→ 機能リスト、オプションのクローズ。スクリーンショットが証拠を運ぶので、ツイートは画像を説明するのではなく、何が存在するようになったかを述べます。画像には一切言及しないでください。

  7. 引き継ぐ。 フレーム版ファイルパスをマークダウンリンクとして、ツイートをフェンスブロックで、さらにフレーム内で投稿前にユーザーが確認すべきものを提供します。

クイックリファレンス

必要な操作コマンド
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アセットです。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル