browser-preview について
browser-previewは、preview_serveで起動したサービスを表示し、問題を調べる方法を説明するスキルです。Previewパネルを使うユーザーやエージェント向けに、サービス状態、履歴、アセットパスの確認手順を示し、localhostではなくプレビューURLへのアクセスを案内します。
主な機能
- 01Previewパネルの動作説明
- 02稼働サービスと履歴の確認
- 03プレビューサービス状態の診断
- 04アセットの絶対パス問題の確認
- 05プレビュー再起動手順
活用シーン
- 01消えたプレビュータブの復旧
- 02白画面やアセット読み込み失敗の調査
- 03履歴からプロジェクトプレビューを再起動
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ starchild-ai-agent/ official-skills --skill browser-previewインストール後、Claude Code で/browser-previewを入力して読み込まれたか確認します。
詳細
ブラウザプレビュー
あなたはすでに preview_serve と preview_stop を理解しています。このスキルはその間を埋めるものです。つまり、preview_serve が URL を返した 後 に何が起こるか——ユーザーが実際にそれをどのように見るかです。
プレビューパネルとは
フロントエンドには、Files と Preview という 2 つのタブを持つ右側のパネルがあります。Preview タブは、プレビュー URL を iframe 内にレンダリングします。preview_serve を呼び出すと、フロントエンドは自動的にその URL を読み込む Preview タブを開きます。(ジョブは現在、右側のパネルではなく、左サイドバーからアクセスできる独立したモーダルで管理されています。)
重要な事実:
preview_serveの呼び出しごとに、1 つの Preview タブが作成されます- URL 形式:
https://<host>/preview/{id}/ - プレビューパネルには ⋮ メニュー(右上)があり、「RUNNING SERVICES」リストが表示されます
- Preview タブは、バックエンドサービスを停止することなく、ユーザーが閉じる ことができます
- バックエンドサービスが停止すると → Preview タブにエラーページが表示されます
⚠️ 重要: ユーザーに localhost へのアクセスを決して指示しないこと
ユーザーのブラウザは localhost や 127.0.0.1 にアクセスできません。 これらのアドレスは、ユーザーのマシンではなく、サーバーコンテナを指しています。プレビューアーキテクチャは リバースプロキシ を使用しています:
User's Browser → https://<host>/preview/{id}/path → (reverse proxy) → 127.0.0.1:{port}/path
ルール:
http://localhost:{port}やhttp://127.0.0.1:{port}にアクセスするようユーザーに 決して 指示しないでください——ユーザーはそこに到達できません- 常に ユーザーをプレビュー URL に誘導してください:
/preview/{id}/(または完全な URLhttps://<host>/preview/{id}/) curl http://localhost:{port}は あなた自身のサーバーサイド診断専用 です——プレビューを「テスト」する方法としてユーザーに提案しないでください- プレビューが実行中の場合は、ユーザーに伝えてください: 「プレビューパネルを確認するか、プレビューパネルを更新してください」
- ユーザーに URL を伝える必要がある場合は、
preview_serveが返すurlフィールドを使用してください(形式:/preview/{id}/)
⚠️ 静的アセットは相対パスを使用する必要があります
プレビューは /preview/{id}/ の下で配信されるため、HTML/JS/CSS 内の絶対パスは壊れます。リバースプロキシはバックエンドに転送する前に /preview/{id} プレフィックスを除去しますが、ブラウザはドメインルートから絶対パスを解決します。
問題の例:
<script src="/static/app.js"></script>
<script src="static/app.js"></script>
<script src="./static/app.js"></script>
修正すべき一般的なパターン:
| 壊れている(絶対パス) | 修正済み(相対パス) |
|---|---|
"/static/app.js" | "static/app.js" または "./static/app.js" |
"/api/users" | "api/users" または "./api/users" |
"/images/logo.png" | "images/logo.png" または "./images/logo.png" |
url('/fonts/x.woff') | url('./fonts/x.woff') |
fetch('/data.json') | fetch('data.json') |
パスが現れる すべての箇所 を確認してください:
- HTML の
src、href属性 - JavaScript の
fetch()、XMLHttpRequest、動的インポート - CSS の
url()参照 - JavaScript の文字列リテラル(例: テンプレート文字列や連結における
'/static/') - フレームワークの設定ファイル(例:
publicPath、base、assetPrefix)
⚠️ 徹底してください——CSS の url() は修正しても、'/static/'(シングルクォート付き)のような JS 文字列リテラルを見落とすことがよくあります。すべてのファイルタイプにわたって、絶対パスのすべての出現箇所を検索してください。
⚠️ プレビューのデバッグのためにファイルシステムを閲覧しないこと
プレビューの状態を把握するために、preview/、output/、その他の任意のフォルダのようなワークスペースディレクトリを 決して 見ないでください。それらはユーザーデータであり、プレビューサービスの状態ではありません。
唯一の 信頼できる情報源:
- レジストリファイル:
/data/previews.json(実行中のサービス) - 履歴ファイル:
/data/preview_history.json(過去のすべてのサービス) preview_serve/preview_stopツールcurlによるポートチェック(サーバーサイドのみ、あなたの診断用)
プレビューの問題を診断するために、ワークスペースディレクトリに対して ls/find を使用しないでください。list_scheduled_tasks のような無関係なツールを呼び出さないでください。集中を保ってください。
ステップバイステップ: プレビューの問題の診断
ユーザーが Preview パネルの問題を報告した場合は、次の正確な順序に従ってください:
ステップ 1: レジストリを読む(実行中のサービス)
cat /data/previews.json 2>/dev/null || echo "NO_REGISTRY"
⚠️ あなたの bash の CWD は /data/workspace/ です。レジストリは /data/previews.json(絶対パス、1 つ上の階層)にあります。常に絶対パスを使用してください。
JSON 構造:
{
"previews": [
{"id": "f343befc", "title": "My App", "dir": "/data/workspace/my-project", "command": "npm run dev", "port": 9080, "is_builtin": false}
]
}
ステップ 2: レジストリの状態に基づいて分岐する
レジストリにエントリがある場合 → ステップ 3(サービスの検証)へ進む レジストリが空または存在しない場合 → ステップ 4(履歴の確認)へ進む
ステップ 3: レジストリにエントリがある — 検証して修正する
レジストリ内の各プレビューについて、ポートがサーバー側で応答しているか確認します(これはあなたの診断用であり、ユーザー向けではありません):
curl -s -o /dev/null -w "%{http_code}" http://localhost:{port}
ポートが応答する場合(200):
- サービスは実行中です。ユーザーに伝えます:
- 「実行中のサービスがあります: {title}」
- 「プレビューパネル右上の ⋮ メニューをクリックし、実行中のサービス一覧でそれをクリックして再度開いてください」
- プレビュー URL:
/preview/{id}/
- ユーザーが ⋮ メニューが空である、またはサービスが表示されないと言った場合 → フロントエンドの同期が失われています。再作成して修正します: レジストリの情報を使って
preview_stop(id)の後にpreview_serve(dir, title, command)を実行します。これによりフロントエンドがタブを再登録します。
ポートが応答しない場合:
- プロセスはクラッシュしましたが、レジストリのエントリは残っています。再作成します:
preview_stop(id="{id}") preview_serve(dir="{dir}", title="{title}", command="{command}")
ステップ 4: 実行中のサービスがない — まず履歴を確認し、次にワークスペースをスキャンする
実行中のサービスがない場合は、2 段階の検索を使用して、ユーザーがプレビューできるプロジェクトを見つけます:
段階 1: プレビュー履歴を読む(推奨 — 高速で正確)
cat /data/preview_history.json 2>/dev/null || echo "NO_HISTORY"
JSON 構造:
{
"history": [
{
"id": "f343befc",
"title": "Trading System",
"dir": "/data/workspace/my-project",
"command": "python main.py",
"port": 8000,
"is_builtin": false,
"created_at": 1709100000.0,
"last_started_at": 1709200000.0
}
]
}
履歴エントリは preview_stop によって削除されることはありません — 再起動をまたいで保持されます。エントリは、プロジェクトディレクトリが存在しなくなった場合にのみ自動的に削除されます。
履歴にエントリがある場合:
- タイトル、ディレクトリ、最終開始時刻とともに、すべての履歴エントリをユーザーに一覧表示します
- どれを再起動したいか尋ねます
- 履歴エントリの
dir、title、commandを使ってpreview_serveを呼び出します
ユーザーがプロジェクトが履歴にないと言った場合 → 段階 2 に進みます。
段階 2: ワークスペースをスキャンする(フォールバック — 履歴が空または不完全な場合)
find /data/workspace -maxdepth 2 \( -name "package.json" -o -name "index.html" -o -name "*.html" -o -name "app.py" -o -name "main.py" -o -name "vite.config.*" \) -not -path "*/node_modules/*" -not -path "*/skills/*" -not -path "*/memory/*" -not -path "*/prompt/*" -not -path "*/.git/*" 2>/dev/null
次に:
- 検出されたプロジェクトを簡単な説明とともに一覧表示します
- どれをプレビューするかユーザーに尋ねます
- 適切なディレクトリを使って
preview_serveを呼び出します
「実行中のサービスはありません」と言って終わるだけにしないでください。 必ず最初に履歴を確認し、次にスキャンして、選択肢を提示してください。
クイックリファレンス
| ユーザーの発言 | あなたの対応 |
|---|---|
| 「タブが消えた」 / 「tab 不见了」 | ステップ 1 → 2 → 3 または 4 |
| 「白いページ」 / 「白屏」 | ポートを確認し(サーバー側)、停止していれば → 再作成、動作していれば → 絶対パスの問題を確認 |
| 「更新されない」 / 「内容没更新」 | プレビュータブの更新ボタンを提案するか、プレビューを再作成 |
| 「ポート競合」 / 「端口冲突」 | preview_stop で古いものを停止 → preview_serve で新しいものを起動 |
| 「サービスが見えない」 / 「⋮ メニューが空」 | preview_stop + preview_serve で強制的に再登録 |
| 「自分のプロジェクトはどこ」 / 「何を作ったっけ」 | /data/preview_history.json を読み、エントリを一覧表示 |
| 「リソースの読み込みに失敗」 / 「JS/CSS 404」 | 絶対パス(/static/、/api/)を確認し、相対パスに修正 |
できないこと
- プレビュータブ(フロントエンド UI)を直接開く/閉じる/更新することはできません
- iframe を強制的に更新することはできません
- iframe が表示している内容を読み取ることはできません
何かできないときは、ユーザーに手動操作を伝えてください(例: 「プレビュータブで更新をクリックしてください」)。手動操作がうまくいかない場合は、preview_stop + preview_serve でプレビューを再作成してください。
避けるべきよくある間違い
- ❌ ユーザーに「http://localhost:18791/ にアクセスしてください」と言う — ユーザーは localhost にアクセスできません
- ❌ 「localhost のページを更新してください」と言う — ユーザーにとって意味がありません
- ❌ CSS の
url()パスだけを修正し、絶対パスを含む JS の文字列リテラルを見落とす - ❌ すべてのファイル種別(HTML、JS、CSS、設定)で絶対パスを確認するのを忘れる
- ✅ ユーザー向け URL としては常に
/preview/{id}/を使用する - ✅
curl localhost:{port}は自分自身のサーバー側診断にのみ常に使用する - ✅ パスを修正した後は、
preview_stop+preview_serveを呼び出して再起動し、ユーザーにプレビューパネルを確認するよう伝える