mcpField
D
debug-broken-ui

debug-broken-ui

github.com/reticlehq開発1.3k250 回インストール今日更新
リポジトリ

debug-broken-ui について

実行中のアプリで操作を再現し、証拠を追ってソース位置を特定する、Reticle向けのUIデバッグスキルです。

主な機能

  1. 01操作を再現して結果を確認
  2. 02ネットワーク、コンソール、状態、ストレージの変化を関連付け
  3. 03要素の表示状態とソース位置を調査
  4. 04明示的な判定で修正を確認

活用シーン

  1. 01クリックでリクエストが発生しない原因の追跡
  2. 02UIとストアの状態不整合の発見
  3. 03遮蔽または無効なコントロールの特定

MCP 対応

Reticleは、このスキルが使うページ検査と操作の機能をMCPツールとして提供します。

インストール

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

$npx skills add https://github.com/reticlehq/reticle --skill debug-broken-ui

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

詳細

アプリが壊れているのに、コードは問題なさそうに見える

ソースを読み直しても、原因はわかりません。証拠は実行中のアプリにありますが、そのほとんどは画面に現れません。失敗したリクエスト、動かなかったストア、バインドされなかったハンドラー、見えない何かに覆われた要素などです。

Reticle はページ内から、そのすべてを読み取ります。まだセットアップしていない場合は、reticle スキルに従ってください。Reticle をインストールし、init によるアプリのファイル変更前にユーザーに確認し、1つのフローで動作を実証します。

推測から始めないでください。再現から始めてください。

reticle_look({ action: "page", sessionId, mode: "interactive" })   // controls only, with refs
reticle_act_and_wait({ sessionId, ref, action: "click", until: { kind: "element", query: { testid: "..." } } })

判定によって、すでに原因を絞り込めています。no / contradicted は、あるチャネルが UI と矛盾するものを検出したことを意味します。バグがあります。unknown は、Reticle が操作を行ったものの判断できなかったことを意味し、「失敗した」とは別の調査が必要です。

ほかのものを呼び出す前に、act の結果を読んでください。 summary ブロックには、その1回のクリックに関する因果関係の全体がすでに含まれています。net {total, errors, headline}、consoleErrors、stateDiffs [{path, from, to}]、storageDiffs [{key, from, to}]、route、signals、layoutShift、longTasks など、件数ではなく、実際の実行前→実行後の差分がわかります。以下のコンソール、ネットワーク、ストレージ、状態の各呼び出しは、サマリーがすでに示した箇所をさらに詳しく調べるためのものです。act の直後に3つすべてを呼び出すと、すでに手元にある証拠のために、モデルとの往復が3回(承認が必要なクライアントでは、ユーザーのクリックも3回)発生します。

summary.stateUnwatched: true は、状態チャネルが機能していないことを意味します。購読可能なストアが登録されていないため、空の stateDiffs は 変化なし ではなく 監視対象外 を意味し、誰かがストアを登録するまでは、状態に基づく結論を出せません。ここにあるフィールドの中で、アプリではなくインストルメンテーションについて示すのはこれだけです。

サマリーが調査箇所を示した場合は、直前の操作にスコープを絞ってそのチャネルを読み取ってください。act の結果から since を渡さないと、クリックより前のバッファを読み取ることになります。

reticle_observe({ action: "console", sessionId, since })
reticle_observe({ action: "network", sessionId, since })
reticle_look({ action: "state", sessionId, store })

診断表

表示されている状況原因次にすること
リクエストがまったく送信されないハンドラーがバインドされていないか、クライアントキャッシュが古い値を返しています対象の要素に reticle_look { action: "element" } を実行して file:line を確認します。TanStack Query を使っている場合はキャッシュを確認します
リクエストは送信されたが、4xx / 5xxUI が隠している、実際のバックエンド障害ですレスポンスボディはネットワークエントリーにあります
2xx だが何も変わらないアプリがレスポンスを読み取っていません。判定には outcome_unread と表示されます多くの場合、成功時の処理に実際のバグがあります
リクエストは正常、DOM も正常、ストアは古いままUI と状態の不整合です。スクリーンショットでは検出できませんreticle_look { action: "state" } だけが確認手段です。ここで最も価値の高い読み取りです
クリックしても何も起きず、エラーもないコントロールが無効、遮蔽、または無効化されていますreticle_look { action: "element" } は、occluded、box(0×0)、styles.cursor、opacity を返します
見えているのに要素が「見つからない」仮想化リストで、まだ要素がマウントされていませんreticle_run({ tool: "reticle_scroll_to", args: { by: "text", value } }) を実行します。find で見つからなくても、存在しない証拠にはなりません
ログイン済みに見えるのに、ログアウト状態のように動作するトークンが保存されていませんreticle_run({ tool: "reticle_storage", args: {} }) を実行します
クリックより前からコンソールエラーがある既存の障害であり、今回のバグではありません続ける前に、その旨を明示します

理論ではなく、ファイルを特定する

reticle_look({ action: "element", sessionId, ref })

調べている要素のコンポーネントと source: { file, line } に加えて、遮蔽されているか、サイズがあるか、無効化されているか、テーマから外れているかを返します。これが開くべきファイルへの手がかりです。仮説ではなく、場所を特定して調査を終えましょう。

フローが長い場合

失敗するステップを探すために、act → snapshot → act → snapshot と行き来しないでください。reticle_act { steps: [...] } で一連の操作を行い、1回だけアサートしてください。結果が失敗した最初のステップを調べればよく、見つけるための呼び出し回数も大幅に減らせます。

修正済みと言う前に

ページを目視で確認するのではなく、判定として再現手順をもう一度実行してください(結果を最初に明示して reticle_act_and_wait を実行します)。見て確認しただけで修正済みと判断することが、このチケットを生んだ失敗パターンです。

そして、合格させるためにチェックを決して弱めないでください。

アプリではなく Reticle 自体のトラブルシューティングについては、curl https://docs.reticle.sh/troubleshooting.md を実行してください。それ以外については、curl https://docs.reticle.sh/llms.txt を実行してください。Reticle が必要なものを認識できなかった場合は、kind: "gap" を指定して reticle_session { action: "feedback" } を実行してください。

コメント