mcpField
D
devtools

devtools

github.com/vercel-labs開発18.8k8.3k 回インストール5 日前に更新
リポジトリ

devtools について

@json-render/devtools は、json-render アプリ向けのフローティングインスペクタです。React、Vue、Svelte、Solid を使う開発者が仕様、状態、アクション、ストリームイベント、カタログを確認でき、要素ピッカーとドック位置の変更にも対応します。

主な機能

  1. 01要素ツリーと検証警告の確認
  2. 02JSON Pointer 状態の表示と編集
  3. 03アクションの実行と結果の追跡
  4. 04仕様ストリームのパッチとイベント確認
  5. 05ページ要素から仕様内の位置を特定

活用シーン

  1. 01AI 生成 UI のデバッグ
  2. 02状態バインディングとアクションの確認
  3. 03複数ターンのストリーム生成の追跡
  4. 04対応フレームワークでのレンダラー検査

インストール

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

$npx skills add https://github.com/vercel-labs/json-render --skill devtools

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

詳細

@json-render/devtools

json-render アプリ向けのフローティングインスペクターパネルです。フレームワークに依存しないコアと、フレームワークごとのアダプター(React、Vue、Svelte、Solid)で構成されています。

本番環境でも安全に使用できます。process.env.NODE_ENV === "production" の場合、ブラウザーに process グローバルがない環境でバンドラーがこの式を置き換える場合も含め、コンポーネントは開発ツールの UI を表示しません。process.env がない未バンドル環境では、開発時の動作を維持します。

インストール

コアパッケージと、ホストアプリのレンダラーに対応するアダプターをインストールします。

# React
npm install @json-render/devtools @json-render/devtools-react

# Vue
npm install @json-render/devtools @json-render/devtools-vue

# Svelte
npm install @json-render/devtools @json-render/devtools-svelte

# Solid
npm install @json-render/devtools @json-render/devtools-solid

ドロップインでの使用

既存の <JSONUIProvider>(または各フレームワークに相当するプロバイダー)の内側で、任意の場所に <JsonRenderDevtools /> を配置します。ほかに必要な設定はありません。

React
import { JsonRenderDevtools } from "@json-render/devtools-react";

<JSONUIProvider registry={registry} handlers={handlers}>
  <Renderer spec={spec} registry={registry} />
  <JsonRenderDevtools spec={spec} catalog={catalog} messages={messages} />
</JSONUIProvider>;
Vue
<script setup>
import { JsonRenderDevtools } from "@json-render/devtools-vue";
</script>

<template>
  <JSONUIProvider :registry="registry">
    <Renderer :spec="spec" :registry="registry" />
    <JsonRenderDevtools :spec="spec" :catalog="catalog" :messages="messages" />
  </JSONUIProvider>
</template>
Svelte
<script>
  import { JsonRenderDevtools } from "@json-render/devtools-svelte";
</script>

<JSONUIProvider {registry}>
  <Renderer {spec} {registry} />
  <JsonRenderDevtools {spec} {catalog} {messages} />
</JSONUIProvider>
Solid
import { JsonRenderDevtools } from "@json-render/devtools-solid";

<JSONUIProvider registry={registry}>
  <Renderer spec={spec()} registry={registry} />
  <JsonRenderDevtools
    spec={spec()}
    catalog={catalog}
    messages={messages()}
  />
</JSONUIProvider>;

コントロール

  • フローティング切り替えボタンが右下に表示されます。
  • ホットキー:Ctrl/Cmd + Shift + J(hotkey prop で設定できます)。
  • ドロワーのサイズを変更できます。高さは localStorage に保存されます。

Props

  • spec (Spec | null) — 現在の spec。
  • catalog (Catalog | null) — カタログ定義。Catalog パネルを使用するには必須です。
  • messages (UIMessage[]) — AI SDK の useChat メッセージ。spec データパーツを検索します。
  • initialOpen (boolean) — 開いた状態で開始します。
  • position ("bottom-right" | "bottom-left" | "right") — ドックと切り替えボタンの位置です。"bottom-*" は画面下部にドックし、"right" は右端に全高でドックします(すでに 100vh または固定の下部バーを使用しているアプリシェルに推奨)。
  • hotkey (string | false) — デフォルトは "mod+shift+j" です。
  • bufferSize (number) — イベントリングバッファーの上限。デフォルトは 500 です。
  • reserveSpace (boolean, default true) — true の場合、body に padding-bottom/padding-right を適用し、パネルがホストアプリを押し出します。パネルを純粋なオーバーレイとして表示するには false を設定します。
  • allowDockToggle (boolean, default true) — ツールバーボタンを表示し、ユーザーがパネルを下部ドックと右側ドックの間で切り替えられるようにします。ユーザーの選択は localStorage に保存され、次回以降のマウントでは position より優先されます。ドック位置を position に固定するには false を渡します。
  • onEvent ((DevtoolsEvent) => void) — 任意のイベントフックです。

パネル

  • Spec — spec.root をルートとする要素ツリー。props/表示状態/イベント/watcher の詳細と、統合された validateSpec の警告を表示します。
  • State — すべての JSON Pointer パスを表示し、store.set でその場で編集できます。
  • Actions — ディスパッチされたアクションのタイムライン(名前、パラメーター、結果/エラー、所要時間)を表示します。
  • Stream — spec パッチ、テキストチャンク、トークン使用量、ライフサイクルマーカーを生成ごとにまとめて表示します。
  • Catalog — カタログで宣言されたコンポーネントとアクションを、prop のチップとともに表示します。

ピッカー(ツールバー)

要素ピッカーはタブではなく、パネルヘッダーのツールバーボタン(Chrome DevTools 風)です。クリックしてピックモードを有効にし、ページ上のレンダリング済み要素をクリックすると、その要素にフォーカスした状態で Spec タブに移動します。キャンセルするには Esc を押します。

スペースの確保とドッキング

パネルは下端または右端にドッキングできます。デフォルトでは、ユーザーはツールバーボタンで2つを切り替えられます(選択は localStorage に保存されます)。ホストアプリが一方のドックしか利用できない場合は、allowDockToggle={false} を設定してください。ボタンが非表示になり、ドックは position に固定されます。

レイアウトに合った初期ドックを選択してください。

  • 下部ドック(デフォルト) — ドキュメント/マーケティング/コンテンツフローのサイトや、height: 100% の連鎖(html { height: 100% } → body { height: 100% } → .app { height: 100% })で構成されたアプリシェルに最適です。パネルは高さを --jr-devtools-offset-bottom に書き込み、body に同じ値の padding-bottom を適用するため、固定配置でないコンテンツには自然にスペースが確保されます。
  • 右部ドック(position="right") — 100vh または position: fixed; bottom: 0 を使用するアプリシェルのレイアウトにおすすめです。右部ドックなら下端を完全に避けられ、幅は --jr-devtools-offset-right に書き込まれます。

100vh、position: fixed、または position: sticky を使用するアプリでは、公開されている CSS カスタムプロパティを使って、特定の要素を対象にできます。

.composer   { bottom: var(--jr-devtools-offset-bottom, 0); }
.sidebar    { right:  var(--jr-devtools-offset-right,  0); }
.app-shell  { height: calc(100vh - var(--jr-devtools-offset-bottom, 0)); }

自動的に適用される body のパディングが特定のレイアウトで問題になる場合は、reserveSpace={false} を渡すと、パネルを純粋なオーバーレイにできます。CSS カスタムプロパティは引き続き公開されるため、必要に応じて手動でスペースを確保できます。

(--jr-devtools-offset は、現在アクティブな端に対応する後方互換用エイリアスとして維持されています。)

1ページ上の複数のレンダラー(例:チャット)

1つの <JsonRenderDevtools /> で、多数の <Renderer /> インスタンスを同時に調査できます。たとえば、アシスタントの各メッセージがそれぞれの spec をレンダリングするチャットや、複数の独立したウィジェットで構成されるダッシュボードなどです。手順は次のとおりです。

  1. トップレベルの <JSONUIProvider> を1つだけ使うことで、すべてのレンダラーが1つの状態ストアとアクションディスパッチャーを共有します。Devtools はこのプロバイダー内に配置し、プロバイダーを通じてすべてを確認します。
  2. レンダラーごとに spec を設定し、状態は共有する — 各アシスタントメッセージは、独自の StateProvider でラップせず、<Renderer spec={msgSpec} registry={registry} /> を直接レンダリングします。異なるメッセージの状態パスが衝突しないようにしてください。
  3. ターンごとに状態を名前空間化する — ソースが AI ストリームの場合、エージェントに一意の messageId を渡し、すべての要素キー(<id>-root)と状態パス(/<id>/count)にその ID を接頭辞として付けるようにします。
  4. spec={latest} と messages={all} を渡す — spec は Spec パネルに表示する内容を決定します(通常は最新のアシスタントメッセージの spec)。一方、messages は Stream パネルにすべてのターンのパッチを渡します。
  5. アクションとピッカーはすでにグローバルです — registerActionObserver はツリー内の任意の ActionProvider からのディスパッチをキャプチャし、data-jr-key はレンダラー自体によって設定されるため、どのメッセージが要素を生成したかにかかわらず、レンダリングされたすべての要素で Pick を使えます。

この方法で構成された AI チャットの完全な例は examples/devtools を参照してください。

命令型 API(React のみ)

import { useJsonRenderDevtools } from "@json-render/devtools-react";

const devtools = useJsonRenderDevtools();
devtools?.open();
devtools?.toggle();
devtools?.recordEvent({ kind: "stream-text", at: Date.now(), text: "hi" });

本番環境、またはコンポーネントのマウント前には null を返します。

サーバーサイドのストリームタップ

API ルートで spec のパッチをキャプチャし、イベントをサーバー側に永続化するか、独自のテレメトリに流し込みます。

import { tapJsonRenderStream, createEventStore } from "@json-render/devtools";
import { pipeJsonRender } from "@json-render/core";

const events = createEventStore({ bufferSize: 1000 });
const tapped = tapJsonRenderStream(result.toUIMessageStream(), events);
writer.merge(pipeJsonRender(tapped));

YAML の同等機能:tapYamlStream。

内部の仕組み

  • Shadow DOM で分離されたパネル — パネルのスタイルはホストアプリに漏れず、ホストアプリのスタイルもパネルに漏れません。
  • リングバッファ方式のイベントストア — Devtools のイベント(状態変更、アクションディスパッチ、ストリームパッチなど)のログを上限付きで保持します。
  • アクションオブザーバーレジストリ — 各フレームワークの ActionProvider は、@json-render/core の notifyActionDispatch/notifyActionSettle を通じて通知します。Devtools は registerActionObserver を通じて購読します。
  • ピッカー用の要素タグ付け — Devtools のマウント中、ElementRenderer はレンダリングされた各要素を <span data-jr-key="..." style="display:contents"> でラップし、ピッカーが DOM から spec キーを特定できるようにします。レイアウトへの影響はありません。

コメント