ui-snapshot について
フロントエンドの画面を単一のオフライン HTML ファイルに移植するスキルです。デザインレビューやドキュメント作成、アプリを実行できない関係者向けに、画面状態やオーバーレイを含めてデスクトップとモバイルで検証します。
主な機能
- 01画面、状態、オーバーレイの洗い出し
- 02元の Tailwind クラスの再利用
- 03プレースホルダーデータでの画面構築
- 04単一のオフライン HTML の生成
- 05デスクトップとモバイル表示の検証
- 06模擬箇所とファイルサイズの報告
活用シーン
- 01アプリを実行できないレビュー担当者への画面共有
- 02サンプルデータを使った UX や QC の検討
- 03プロジェクト資料へのオフライン UI デモ掲載
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rheinmir/ setup --skill ui-snapshotインストール後、Claude Code で/ui-snapshotを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/app-skeleton.jstemplate.htmlscripts/build.pyshot.mjs詳細
スキル:ui-snapshot
bonbon-ai の 2026-09-19 のセッションからまとめました:fe/(Next.js 14、
Tailwind 3)の 12 画面 × デスクトップ/モバイルと 10 個のオーバーレイを 426 KB に収め、Playwright で 22 枚を撮影、コンソールエラーは 0 件でした。
概要
目的とコンテキスト
- 目的: ダブルクリックで開ける単一の
.htmlファイル(サーバー不要、ネットワーク不要、ログイン不要)で、実際のアプリの UI を正確に再現します。レイアウト、色トークン、フォント、アイコン、状態(読み込み中/空/エラー/期限超過など)、オーバーレイ(モーダル、シート、トースト、ツアー)を、固定のプレースホルダーデータで表現します。 - 使用するタイミング:
- アプリを実行できない人(上司、デザイナー、顧客、レビュー担当者、Wiki 資料)に UI を見せる必要がある場合。
- 実データやバックエンドに触れずに、UX/品質確認のためのサンプルデータ入りモックアップが必要な場合。
- ユーザーが「UI スナップショット」「UI を 1 つの html ファイルにまとめて」「プロジェクトの UIUX を圧縮して」、または
/ui-snapshotと言った場合。
- 対象外: 再設計はしません(→hallmark/redesign)。実行中のアプリを静止画として撮影することもしません(→playwright-verify)。実データを含めず、ビジネスロジック/API も維持しません(操作ボタンはページ内の状態だけを変更します)。
メンタルモデル
実際のアプリをビルド/SSR するのではなく PORT する理由:実際のアプリには認証+バックエンド+実データが必要です。また、実際の DOM を使ったスナップショットには、機密データや大きなバンドルが含まれてしまいます。vanilla JS に移植し、クラスを原文どおりにコピーし、実際の設定で Tailwind をコンパイルすれば、余計なものを持ち込まず、ピクセル単位で正確に再現できます。
各ページの JSX をすべて読む → 画面+状態+オーバーレイを列挙する → app.js を作成する(ハッシュルーター、状態、固定データ、画面ごとに 1 関数、デスクトップ/モバイル分岐) → build.py(実際の Tailwind 設定+フォント+アイコンのサブセット+アセットの data URI) → shot.mjs で検証 → 修正 → 公開
入力と出力の契約
| 項目 | 必須? | 意味 | |
|---|---|---|---|
| 入力 | node_modules を含むフロントエンドディレクトリ(--fe) | はい | tailwindcss CLI とプロジェクトの設定を使用するため |
| 入力 | ページ/ルートの一覧 | はい(app/**/page.tsx、pages/、src/routes を自動検出) | 「UI 全体」の範囲 |
| 入力 | ファイルサイズの上限 | いいえ(5 MB) | --max-mb |
| 入力 | メインフォント/ロゴ/バナー | いいえ | --font、--asset NAME=path |
| 出力 | <repo>/…/DDMMYY-<project>-uiux-snapshot.html | はい | 単一のオフラインファイル |
| 出力 | レポート:画面数、KB、検証画像、実際のアプリとの差異 | はい | 正確な報告と、シミュレートした箇所の列挙 |
ルールと機能
- RULE-01(必須):移植する前に、各ページの JSX ファイルをすべて読むこと(モバイル分岐、空/読み込み中/エラー、モーダル、シートも含む)。記憶を頼りに移植すると UI がずれます。
- RULE-02(必須):Tailwind クラスは JSX から原文どおりにコピーし、
app.jsにリテラル文字列として記述すること(JIT が認識するのはリテラルのみです。bg-${x}のように動的に組み立てるとクラスが失われます)。 - RULE-03(必須):プレースホルダーデータは固定し、実データは絶対に使わないこと(API を呼び出さず、ネットワークキャプチャ/DB からコピーしません)。期限超過状態を時間が経っても安定させるため、日付には相対オフセット(
D(-9))を使います。 - RULE-04(必須):アイコン名は
build.pyがフォントをサブセット化できるよう、引用符付き文字列("search")で記述すること。動的アイコンの場合は、マップに完全な名前を設定します。 - RULE-05(必須):アプリと同じブレークポイント(例:768px)を使い、JS でデスクトップ/モバイルの分岐をレンダリングすること(スマートフォン枠内でモバイルを強制するモードがある場合、
md:に頼らないでください)。 - RULE-06(必須):外部アセット(CDN の画像、Google Fonts)は埋め込むか、背景色/グラデーションに置き換えること。ファイルはオフラインで動作する必要があります。置き換えた箇所はすべてレポートに明記します。
- RULE-07(必須):
shot.mjsでデスクトップとモバイルの両方を検証し、画像を確認して、NO ERRORSになってから完了を報告すること。--max-mbを超えた場合は FAIL です。 - RULE-08(推奨):デモパネル(「UI」ボタン)を用意し、すべての画面への移動と各状態(読み込み中/古いデータ、エラー、トースト、ツアー、AI の各状態など)の切り替えを可能にすること。また、Auto/Desktop/Mobile モードも設けます。
- 機能:コードベースの読み取り、Python 3+Node+プロジェクトの Tailwind CLI、ビルド時のネットワーク(Google Fonts、コードポイント)、検証用の Playwright。
失敗時の境界
- プロジェクトで Tailwind を使用していない場合 →
build.pyで CSS が空になります。CSS モジュールや styled の内容を手動でテンプレートにコピーするか、ユーザーに確認してください。 - ビルド時にネットワークに接続できない場合 → フォントやアイコンを埋め込めません → ブロックします(またはシステムフォントへのフォールバックを許容し、その旨を明記します)。
- ファイルが上限を超える場合 → 不要なフォントのウェイトを削除し、画像を
sips -Zでさらに小さくし、サンプルデータを減らします。画面は削除しません。 - 別のフレームワーク(Vue/Svelte/Angular のテンプレート)の場合 → 手順はそのまま適用し、クラスの読み取り元だけを変更します。
方法
メインワークフロー
| Step | Type | Inputs | Action | Outputs/exit | Failure/next |
|---|---|---|---|---|---|
| W01 | deterministic | --fe | ルート、レイアウト、共通コンポーネントを調査します。tailwind.config、globals.css、design.md があれば読み取ります | 画面一覧 + トークン | Tailwind がない → FB1 |
| W02 | judgment | 各ページの JSX | 各ページをすべて読み(RULE-01)、すべての状態/オーバーレイ/モバイル分岐を記録します | 画面 × 状態の一覧 | — |
| W03 | effect | inventory | assets/app-skeleton.js から <scratch>/app.js を、assets/template.html から template.html を作成します(__TITLE__、__FONT__ を置換)。各画面を移植し、クラスは原文のまま、データは固定します | app.js | — |
| W04 | deterministic | app.js + template | python3 scripts/build.py --fe <fe> --src <scratch> --out <file> --font "<Font>" --asset LOGO=public/logo.png | HTML ファイル + KB | Tailwind エラー → stderr を確認;>max → FB3 |
| W05 | deterministic | file | node scripts/shot.mjs <file> <scratch>/shots d-home=home m-home=home … を実行します(不足している場合は playwright を scratch にインストール)。その後、画像を確認します | 画像 + NO ERRORS | エラー → app.js を修正し、W04 を繰り返す |
| W06 | effect | file | リポジトリに配置します(例:llmwiki/html/DDMMYY-<project>-uiux-snapshot.html)。プロジェクトに Wiki があればログを記録し、画面数、KB、シミュレーションした箇所を報告します | 報告 | — |
分岐
| ID | Kind | Guard | Hành vi | Skip / failure | Rejoin |
|---|---|---|---|---|---|
| B01 | conditional | デッドコードの UI(到達経路のない状態)があるページ | 移植しますが、デモパネルからのみ開けるようにし、「legacy」と注記します | — | W03 |
| B02 | conditional | アプリに暗色/別のデザインシステムを使う開発ツールページがある | 元の実装どおり、インラインスタイルで移植します | — | W03 |
| B03 | recovery | 広い画面でモバイルモードのレイアウトがずれる | #frame に transform を設定して fixed がフレームに追従するようにします。#app はスクロール領域にします。.h-screen/.min-h-screen を 100% に上書きします(テンプレートに設定済み) | — | W05 |
検証と停止条件
必須条件:build.py が終了コード 0 で完了し、ファイルサイズが上限未満であること。shot.mjs がすべてのデスクトップ画面とモバイル画面について NO ERRORS を出力すること。目視確認:実際のアプリ/Figma と画像を比較します(色、間隔、ベトナム語のアクセント記号)。一覧にあるすべての画面で問題のない画像が取得でき、シミュレーションした箇所が報告に記載されたら終了します。
例
- 成功例: bonbon-ai
fe/→ ログイン、ダッシュボードの概要/保留中/期限超過、部署/契約種別でのフィルター、3 タブのチケット詳細、VS Code オーバーレイ、AI トラッカー、シート/モーダル/トースト/ツアー → 426 KB、79 個のアイコン、22 枚の画像を検証、エラー 0 件。 - 境界例: CDN の 3 MB のヒーロー背景画像 → ファイルが上限を超えるため、グラデーションに置き換え、「実際のアプリとの差異:ログイン背景画像」と記載します。
決定論的テスト
assets/app-skeleton.js(名前を app.js に変更)と assets/template.html を使って python3 scripts/build.py --fe <fe> --src assets-copy --out /tmp/t.html を実行し、1 MB 未満のファイルが生成されることを確認します。続いて node scripts/shot.mjs /tmp/t.html /tmp/shots d-home=home m-home=home を実行し、NO ERRORS が出力されることを確認します。