mcpField
P
pr-screenshot-comparison

pr-screenshot-comparison

github.com/petekpテスト・品質4885 回インストール2 日前に更新
リポジトリ

pr-screenshot-comparison について

pr-screenshot-comparison は、PR の見た目の変更をレビューしやすくする比較画像を作成するワークフローです。指定したベースと PR のコミット上で実際の製品画面を撮影し、条件を揃えて偽の証拠を避けます。

主な機能

  1. 01指定コミットの実際の製品画面を撮影
  2. 02ビューポート、ズーム、テーマ、状態を統一
  3. 03比較パネルを縦に配置
  4. 04添付前に画像とプレビューを確認
  5. 05スクリーンショットをリポジトリ外に保管

活用シーン

  1. 01ベースと PR の UI 変更を比較
  2. 02操作部品の前後と有効化状態を提示
  3. 03PR レビュー用に見た目の変更を記録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/petekp/claude-code-setup --skill pr-screenshot-comparison

インストール後、Claude Code で/pr-screenshot-comparisonを入力して読み込まれたか確認します。

同梱ファイルagents/openai.yamlscripts/compose.py

詳細

PR のスクリーンショット比較

UI の変更を視覚的に簡単に評価できる、レビューしやすい画像を 1 枚作成します。

プロダクトの証拠に関するルール

PR のスクリーンショットは、デザインのイラストではなく、プロダクトの証拠です。各パネルは、ベースコミットまたは PR コミットで動作している実際のプロダクトのルートから取得する必要があります。また、実際のアプリシェル、ルーティング、認証境界、データ経路を使用する必要があります。

コンポーネントハーネス、Storybook のストーリー、静的な再現画面、捏造した遷移先ページ、モックデータの画面は、プロダクトの証拠として認められません。これらを PR に添付したり、アプリケーションのスクリーンショットとして説明したりしないでください。

認証またはデータの問題でルートにアクセスできない場合:

  1. プロジェクトで正式に使われているローカル環境を起動するか、再利用します。
  2. 利用可能な認証済みブラウザーセッションがあれば、それを再利用します。ユーザーによるサインインが必要な場合は、必要最小限の引き継ぎを依頼します。
  3. 実際のルートに引き続きアクセスできない場合は、作業を中止して、ブロッカーを報告します。捏造した証拠を提示するより、スクリーンショットがないほうが正確です。

ユーザーがコンポーネントレベルの証拠を明示的に求めた場合に限り、ハーネスを作成します。画像と PR の説明文で「コンポーネントハーネス」と明記してください。プロダクトのスクリーンショットと混在させたり、代用したりしないでください。

内部データポリシー

非公開または内部向けであることが確認された PR では、PHI を含め、画面上に実際のプロダクトデータを使用します。プライバシー保護だけを理由に、氏名、記録、コンテンツを偽のデータに置き換えないでください。これらのスクリーンショットは内部レビュー用の成果物です。

ただし、認証情報、アクセストークン、パスワード、API キー、無関係な機密データは除外してください。一般公開される PR や外部から閲覧可能な PR では、キャプチャ前に機密データを最小限にするか、マスキングしてください。

キャプチャと合成

  1. 検証内容を定義します。正確なベース/ヘッドのコミット、製品のルート、データ、CSS ピクセル単位のビューポート、ブラウザーのズーム、テーマ、必要な操作状態を指定します。重要な変更点を列挙し、それらを検証するか、PR の説明文で対象外の項目を明示します。新しい主要コントロールの場合は、変更前、変更後(未操作)、**変更後(操作後)**を使用します。それ以外の場合は、変更前、変更後を使用します。
  2. 一連のキャプチャを取得する前に、状態が安定した画面を1つ撮影します。配信中のコミット、読み込まれたレコード、フォント、画像、スクロール位置を確認します。サーバーの準備完了やナビゲーションの完了だけでは、コンテンツが安定した証拠になりません。実演する操作以外では、メニュー、フォーカス、ポインター、パネルの状態を一致させます。
  3. 選択したブラウザーツールを使って、画面全体を含む非可逆圧縮なしの PNG を保存します。実際のピクセル寸法を CSS ビューポートの寸法と並べて記録します。それらの値からピクセルと CSS の倍率を算出します。devicePixelRatio やクリッピング API が同じ座標系を使用すると想定しないでください。この最初のキャプチャを確認してから、再撮影してください。撮影時に、予期しない拡大縮小、空白の余白、読み込み中の状態、コンテンツの切り抜けがあれば、そのキャプチャは使用しないでください。
  4. 正確なコミット上で、同じビューポート、ズーム、データ、テーマ、ブラウザーのキャプチャ方法を使って、ほかの状態も撮影します。別々のワークツリーを使うか、元に戻せるクリーンチェックアウトを行ってください。その後、PR のチェックアウトに戻し、PR のコードが配信されていることを確認します。
  5. 保存済みのオリジナル画像から、同じ CSS 矩形を画像ピクセルに変換して切り抜きます。変更箇所が分かるよう、コントロール全体、開いたメニュー、その周囲の十分なコンテキストを含めます。端の余白を保ち、ラベル、見出し、メニュー、吹き出しを途中で切らないでください。これらの状態をまとめると幅が広すぎて PR 上で読めない場合は、証拠を示す範囲を狭めるか、画面全体を縮小する代わりに詳細の比較を別に作成します。
  6. 標準の縦積み比較には scripts/compose.py を使用します。スクリーンショットのピクセルを保持し、寸法と切り抜き範囲を検証して、一貫したラベルと説明文を描画します。アップロード用 PNG とレビュー用プレビューが生成されます。標準レイアウトの代わりに、その場しのぎの画像連結スクリプトを使わないでください。このレイアウトで変更箇所を示せない場合は別のレイアウトが適切です。その場合も以下の注釈ルールを守り、例外の理由を説明してください。
  7. 高解像度画像だけでなく、プレビューも確認します。Herdr 内で、合成した PNG をターミナルとブラウザーの分割画面で開き、添付前に Pete が確認できるようにします。必要なラベルと ID は、ズームなしで読める必要があります。関連する状態がすべて揃っていること、切り抜きが揃っていること、注釈が証拠を隠していないことを確認します。問題があれば、アップロード前に再撮影するか、フレームを調整してください。小さなキャプチャを拡大したり、シャープ化したり、説明文を追加したりしても、失われた証拠は復元できません。
  8. 以下の添付手順に従い、必要なアップロード許可を得て、確認済みの PNG のみを添付します。PR を再読み込みし、埋め込み時の実際のサイズで画像を確認します。アップロードに成功したことや画像の寸法がゼロでないことは、目視確認の代わりにはなりません。

注釈の基準

注釈は製品のピクセル領域の外側に配置します。標準のビジュアルスタイルにはコンポジターを使用します。

  • パネルを縦に並べ、それぞれがレビュー可能な幅を最大限使えるようにします。外側の余白は 20 CSS px、パネル間の間隔は 24 px、ヘッダーの高さはすべて同じにします。ラベル、キャプション、スクリーンショットはすべて同じ左端に揃えます。
  • macOS では Arial のレギュラー/ボールド、Linux では DejaVu Sans のレギュラー/ボールドを使用するか、同等のサンセリフ書体の組み合わせを明示的に指定します。選択した書体の組み合わせは PR 全体で統一します。ビットマップフォントへ暗黙にフォールバックしたり、パネルごとに書体を変えたりしないでください。
  • 状態ラベルは 16 px のボールド、説明キャプションは 14 px のレギュラー、行間は 20 px とし、最大 2 行に収めます。Before/After は説明とは分けて配置します。コミットハッシュとルートの詳細は、画像ヘッダーではなく PR の説明文に記載します。
  • キャプチャした UI に合わせて、コンポジターの明るい色または暗い色のニュートラルなフレームを、パネル間で一貫して使用します。テキストのコントラスト比は 4.5:1 以上にします。製品のキャプチャ画像に色を付けたり、状態の伝達に赤と緑だけを使ったりしないでください。
  • 実装ではなく、目に見える違いを説明します。「リストの祖先」/「顧客の祖先」のように、対応するキャプションを付けます。状態ラベルを単に繰り返すだけのキャプションは省略します。
  • キャプションだけでは変更箇所が曖昧な場合に限り、番号付きのコールアウトを追加します。通常は 3 つ以内にします。画像に合わせて、直径 20 px の円形マーカー、12 px のボールドの数字、1.5 px の引き出し線を使用します。同じ対象にはパネル間で同じ番号を使います。説明は一貫した外部の凡例に配置します。引き出し線は対象を正確に指し、テキストと交差したり、コントロールを隠したりしないようにします。標準のコンポジターでは、意図的にオーバーレイを追加しません。コールアウトが必要な場合も、画像を作り直さず、フレームと書体をそのまま維持してください。
標準コンポジター

利用可能なアーティファクト環境に Python 3 と Pillow が必要です。製品リポジトリに依存関係をインストールしないでください。キャプチャマニフェスト、画像、出力は Git の外に保存します。マニフェスト内のパスは、マニフェストファイルからの相対パス、または絶対パスです。

{
  "viewport": [1020, 971],
  "crop": [64, 6, 640, 172],
  "frame": "dark",
  "panels": [
    {"label": "Before", "caption": "List ancestor", "image": "before.png", "commit": "BASE_SHA", "route": "/appraisals/record-id"},
    {"label": "After at rest", "caption": "Customer ancestor; eyebrow retained", "image": "after.png", "commit": "HEAD_SHA", "route": "/appraisals/record-id"},
    {"label": "After activated", "caption": "Related records with IDs aligned right", "image": "open.png", "commit": "HEAD_SHA", "route": "/appraisals/record-id"}
  ]
}

crop は CSS ピクセル単位の [x, y, width, height] です。例の寸法、識別情報、キャプションはすべて、実際に測定したキャプチャの情報に置き換えます。異なるローカルオリジン間で比較できるよう、相対ルートを使用します。

python3 <skill-directory>/scripts/compose.py /tmp/comparison.json /tmp/comparison.png

コンポジターは、画像サイズの不一致、不均一な拡大率、縮小されたキャプチャ、範囲外のクロップ、長すぎるキャプション、幅が 680 CSS px を超えるクロップを拒否します。この幅なら、およそ 720 px のレビュー列内にフレームを収める余地があります。アップロード用 PNG では画像のネイティブな密度を維持し、確認用に別途 -preview.png を出力します。コミットの出所、コンテンツの準備状況、プライバシー、クロップに適切なコントロールが写っているかは検証できません。これらは実際の製品と両方の出力を確認する必要があります。

ルール

  • 製品のスクリーンショットはすべて、指定されたコミットの実際の製品ルートから取得する必要があります。UI、レコード、遷移先ページを捏造しないでください。
  • 認証やデータの問題でブロックされた場合に、ハーネスを代替として使用しないでください。コンポーネントレベルの証拠が明示的に求められた場合に限り使用し、その旨を明確に示してください。
  • PR の PNG をリポジトリ、.github/assets、PR ブランチに追加しないでください。これは PR の補足情報であり、製品ソースではありません。
  • PR 画像にリポジトリの非公開ファイルへの生の URL を使用しないでください。レビュー担当者に表示されない場合があります。永続的に利用できる方法として、GitHub の標準添付機能を使用してください。
  • キャプチャ用ハーネス、フィクスチャ、Vite の変更、スクリーンショット用ツールをブランチに残さないでください。git diff <base>...HEAD に画像アセットやキャプチャコードが含まれていないことを確認します。
  • ビューポート、ズーム、テーマ、コンポーネントの状態を一致させます。異なる場合にその差を明示していない比較は無効です。
  • 表示中のテーマを示す目的だけで、PR の説明文、見出し、画像キャプション、代替テキストに「ダークモード」や「ライトモード」と記載しないでください。変更内容を説明します。テーマ固有の動作が変更に含まれる場合、または比較がテーマの違いに依存する場合に限り、テーマに言及してください。

推奨する PR の文面

短い見出しのあとに、ローカルパスで参照した画像を置き、続けて一文を書きます。

### Visual comparison

![Before and after: the hover state no longer clips the checkbox](./compare.png)

Before: [old behavior]. After: [new behavior].

意味のある視覚的な違いを一文で説明します。画像が一つの状態やテーマしか示していない場合、すべての表示を網羅しているとは主張しないでください。

gh で添付する

画像リンクをアップロード、再利用、修復する前に、 GitHub の添付リンクを永続化するに従ってください。 エディターまたは PR 本文の生データから取得した元のアップロード URL を保持し、レンダリングされた画像の src、currentSrc、またはリダイレクトをたどった後に取得した URL は使用しないでください。

gh pr create、gh pr edit、gh pr comment では --attach '<file>#<alt text>' を指定します(gh 2.99.0 以降。gh --version で確認してください)。gh はファイルをアップロードし、本文内の一致するローカルパスをホストされたアセット URL に書き換えて、代替テキストを保持します。本文を指定するフラグがない場合は、既存の本文の末尾に画像を追加します。

画像を見出しの下に配置するには、上記の文面を現在の本文に追加し、同じコマンドで添付します。

gh pr view <number> --json body --jq .body > "$TMPDIR/pr-body.md" || exit 1
cat >> "$TMPDIR/pr-body.md" <<'EOF'
<the PR copy above>
EOF
python3 "$HOME/.codex/skills/pr-description/scripts/check_attachment_urls.py" "$TMPDIR/pr-body.md" || exit 1
gh pr edit <number> --body-file "$TMPDIR/pr-body.md" --attach './compare.png#Before and after: ...' || exit 1
gh pr view <number> --json body --jq .body > "$TMPDIR/pr-body-saved.md" || exit 1
python3 "$HOME/.codex/skills/pr-description/scripts/check_attachment_urls.py" "$TMPDIR/pr-body-saved.md" || exit 1

本文内のパスは、--attach に渡すパスと一致している必要があります。複数のファイルを添付する場合は、このフラグを繰り返し指定でき、1 コマンドあたり最大 50 個まで指定できます。対応形式:PNG、JPEG、GIF、WebP、SVG、MP4、MOV、WebM。画像の上限は 10 MB です。アップロードにはリポジトリへの書き込みアクセスが必要です。また、GitHub Enterprise Server はサポートされていません。

gh が 2.99.0 より古い場合、またはリポジトリが GitHub Enterprise Server 上にある場合に限り、ウェブエディターを使用してください。PNG を説明欄にドラッグし、保存して、正しく表示されることを確認します。

コメント