{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "graphql-query-explorer",
  "title": "Graphql Query Explorer",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/graphql-query-explorer/GraphqlQueryExplorer.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  AlignLeft,\n  Check,\n  ChevronDown,\n  ChevronUp,\n  Copy,\n  FileCode,\n  Globe,\n  History,\n  Loader2,\n  Play,\n  Zap,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card } from '@/components/ui/card'\nimport { GraphqlSchemaSidebar } from './GraphqlSchemaSidebar'\nimport { GraphqlTracingPanel } from './GraphqlTracingPanel'\nimport { type QueryPreset, type SchemaField } from './graphql-query-explorer-types'\n\nexport interface GraphqlQueryExplorerProps {\n  className?: string\n}\n\nconst presets: QueryPreset[] = [\n  {\n    id: 'preset-customer',\n    name: 'GetCustomerProfile',\n    operationType: 'query',\n    query: `query GetCustomerProfile($id: ID!) {\n  customer(id: $id) {\n    id\n    name\n    email\n    avatarUrl\n    status\n    createdAt\n    subscriptions {\n      id\n      status\n      plan\n      renewalDate\n      seats\n    }\n    billingAddress {\n      city\n      country\n      postalCode\n    }\n  }\n}`,\n    variables: `{\\n  \"id\": \"cust_8492\"\\n}`,\n    response: {\n      data: {\n        customer: {\n          id: 'cust_8492',\n          name: 'Sarah Jenkins',\n          email: 'sarah.jenkins@acme-corp.io',\n          avatarUrl: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330',\n          status: 'ACTIVE',\n          createdAt: '2024-03-15T08:22:19Z',\n          subscriptions: [\n            {\n              id: 'sub_9812',\n              status: 'ACTIVE',\n              plan: 'ENTERPRISE_ANNUAL',\n              renewalDate: '2027-03-15',\n              seats: 48,\n            },\n            {\n              id: 'sub_4410',\n              status: 'CANCELED',\n              plan: 'STARTER_TRIAL',\n              renewalDate: '2024-04-01',\n              seats: 5,\n            },\n          ],\n          billingAddress: {\n            city: 'San Francisco',\n            country: 'US',\n            postalCode: '94107',\n          },\n        },\n      },\n      extensions: {\n        tracing: {\n          version: 1,\n          duration: 64120000,\n        },\n      },\n    },\n    latency: '64ms',\n    size: '1.8 kB',\n    timestamp: 'Just now',\n  },\n  {\n    id: 'preset-users',\n    name: 'ListUsers',\n    operationType: 'query',\n    query: `query ListUsers($limit: Int, $offset: Int) {\n  users(limit: $limit, offset: $offset) {\n    id\n    fullName\n    email\n    role\n    isVerified\n    lastActiveAt\n  }\n}`,\n    variables: `{\\n  \"limit\": 3,\\n  \"offset\": 0\\n}`,\n    response: {\n      data: {\n        users: [\n          {\n            id: 'usr_9011',\n            fullName: 'Alex Rivera',\n            email: 'alex.rivera@uipkge.dev',\n            role: 'ADMIN',\n            isVerified: true,\n            lastActiveAt: '2026-08-21T10:45:00Z',\n          },\n          {\n            id: 'usr_9012',\n            fullName: 'Elena Rostova',\n            email: 'elena.r@uipkge.dev',\n            role: 'DEVELOPER',\n            isVerified: true,\n            lastActiveAt: '2026-08-21T09:12:30Z',\n          },\n          {\n            id: 'usr_9013',\n            fullName: 'Marcus Chen',\n            email: 'marcus.chen@uipkge.dev',\n            role: 'MEMBER',\n            isVerified: false,\n            lastActiveAt: '2026-08-20T18:04:12Z',\n          },\n        ],\n      },\n    },\n    latency: '38ms',\n    size: '0.9 kB',\n    timestamp: '2 mins ago',\n  },\n  {\n    id: 'preset-create-order',\n    name: 'CreateOrder',\n    operationType: 'mutation',\n    query: `mutation CreateOrder($input: CreateOrderInput!) {\n  createOrder(input: $input) {\n    order {\n      id\n      status\n      totalAmount\n      currency\n      itemsCount\n      createdAt\n    }\n    clientSecret\n    error {\n      code\n      message\n    }\n  }\n}`,\n    variables: `{\\n  \"input\": {\\n    \"customerId\": \"cust_8492\",\\n    \"items\": [\\n      { \"sku\": \"SKU_PRO_REGISTRY\", \"quantity\": 1, \"price\": 149.00 }\\n    ],\\n    \"currency\": \"USD\"\\n  }\\n}`,\n    response: {\n      data: {\n        createOrder: {\n          order: {\n            id: 'ord_88201',\n            status: 'PENDING_PAYMENT',\n            totalAmount: 149.0,\n            currency: 'USD',\n            itemsCount: 1,\n            createdAt: '2026-08-21T12:00:00Z',\n          },\n          clientSecret: 'pi_3Mtwx2_secret_9941a8',\n          error: null,\n        },\n      },\n    },\n    latency: '112ms',\n    size: '1.1 kB',\n    timestamp: '5 mins ago',\n  },\n  {\n    id: 'preset-subscription-stream',\n    name: 'OnOrderStatusChanged',\n    operationType: 'subscription',\n    query: `subscription OnOrderStatusChanged($orderId: ID!) {\n  orderStatusUpdated(orderId: $orderId) {\n    orderId\n    previousStatus\n    newStatus\n    updatedAt\n    carrierTracking {\n      carrier\n      trackingNumber\n      estimatedDelivery\n    }\n  }\n}`,\n    variables: `{\\n  \"orderId\": \"ord_88201\"\\n}`,\n    response: {\n      data: {\n        orderStatusUpdated: {\n          orderId: 'ord_88201',\n          previousStatus: 'PROCESSING',\n          newStatus: 'SHIPPED',\n          updatedAt: '2026-08-21T12:05:44Z',\n          carrierTracking: {\n            carrier: 'FedEx Priority',\n            trackingNumber: 'FDX-9982-1049-US',\n            estimatedDelivery: '2026-08-23T16:00:00Z',\n          },\n        },\n      },\n    },\n    latency: '18ms',\n    size: '0.7 kB',\n    timestamp: '12 mins ago',\n  },\n]\n\nfunction escapeHtml(str: string): string {\n  return str\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&#039;')\n}\n\nfunction highlightJsonLine(line: string): string {\n  if (!line) return ''\n  const escaped = escapeHtml(line)\n  return escaped.replace(\n    /(&quot;(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*&quot;(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g,\n    (match) => {\n      let cls = 'text-warning'\n      if (/^&quot;/.test(match)) {\n        if (/:$/.test(match)) {\n          cls = 'text-info font-medium'\n        } else {\n          cls = 'text-success'\n        }\n      } else if (/true|false/.test(match)) {\n        cls = 'text-chart-2 font-semibold'\n      } else if (/null/.test(match)) {\n        cls = 'text-destructive italic'\n      }\n      return `<span class=\"${cls}\">${match}</span>`\n    },\n  )\n}\n\nfunction highlightGraphqlLine(line: string): string {\n  if (!line) return ''\n  const escaped = escapeHtml(line)\n  if (escaped.trim().startsWith('#')) {\n    return `<span class=\"text-muted-foreground/60 italic\">${escaped}</span>`\n  }\n\n  // Park each emitted <span> behind a letter-only placeholder: the type pass\n  // (`:\\s*Type`) otherwise matched the `dark:text-...` inside markup an earlier\n  // pass had already inserted, splitting the class attribute.\n  const parked: string[] = []\n  const park = (html: string) => {\n    const key = String(parked.length)\n      .split('')\n      .map((d) => String.fromCharCode(97 + Number(d)))\n      .join('')\n    parked.push(html)\n    return `\\u0000${key}\\u0000`\n  }\n\n  return escaped\n    .replace(/\\b(query|mutation|subscription|fragment|on)\\b/g, (m) =>\n      park(`<span class=\"text-info font-semibold\">${m}</span>`),\n    )\n    .replace(/(\\$[a-zA-Z0-9_]+)/g, (m) => park(`<span class=\"text-success font-medium\">${m}</span>`))\n    .replace(/:\\s*([A-Za-z0-9_\\[\\]!]+)/g, (_, t) => ': ' + park(`<span class=\"text-chart-1 font-mono\">${t}</span>`))\n    .replace(/(@[a-zA-Z0-9_]+)/g, (m) => park(`<span class=\"text-warning\">${m}</span>`))\n    .replace(/\\u0000([a-j]+)\\u0000/g, (_, key: string) => {\n      const idx = Number(\n        key\n          .split('')\n          .map((c: string) => String(c.charCodeAt(0) - 97))\n          .join(''),\n      )\n      return parked[idx] ?? ''\n    })\n}\n\nfunction prettifyGraphql(queryStr: string): string {\n  const lines = queryStr.split('\\n')\n  let indentLevel = 0\n  const formatted: string[] = []\n\n  for (const rawLine of lines) {\n    const line = rawLine.trim()\n    if (!line) continue\n\n    if (line.startsWith('}') || line.startsWith(')')) {\n      indentLevel = Math.max(0, indentLevel - 1)\n    }\n\n    formatted.push('  '.repeat(indentLevel) + line)\n\n    if (line.endsWith('{') || line.endsWith('(')) {\n      indentLevel++\n    }\n  }\n\n  return formatted.join('\\n')\n}\n\nexport function GraphqlQueryExplorer({ className }: GraphqlQueryExplorerProps) {\n  const [endpointUrl, setEndpointUrl] = React.useState('https://api.uipkge.dev/graphql')\n\n  const [editorMode, setEditorMode] = React.useState<'edit' | 'preview'>('edit')\n  const [activeCenterTab, setActiveCenterTab] = React.useState<'variables' | 'headers'>('variables')\n  const [isVariablesCollapsed, setIsVariablesCollapsed] = React.useState(false)\n  const [activeResponseTab, setActiveResponseTab] = React.useState<'response' | 'tracing' | 'headers'>('response')\n\n  const [isLoading, setIsLoading] = React.useState(false)\n  const [copiedResponse, setCopiedResponse] = React.useState(false)\n  const [showHistoryDropdown, setShowHistoryDropdown] = React.useState(false)\n\n  const [activeQuery, setActiveQuery] = React.useState(presets[0].query)\n  const [activeVariables, setActiveVariables] = React.useState(presets[0].variables)\n  const [activeHeaders, setActiveHeaders] = React.useState(\n    `{\\n  \"Authorization\": \"Bearer uipkge_live_9f81a7\",\\n  \"X-Tenant-ID\": \"tenant_prod_eu\"\\n}`,\n  )\n  const [responseJson, setResponseJson] = React.useState<Record<string, unknown>>(presets[0].response)\n  const [responseStatus, setResponseStatus] = React.useState('200 OK')\n  const [responseLatency, setResponseLatency] = React.useState('64ms')\n  const [responseSize, setResponseSize] = React.useState('1.8 kB')\n\n  const queryLines = React.useMemo(() => activeQuery.split('\\n'), [activeQuery])\n  const variableLines = React.useMemo(() => activeVariables.split('\\n'), [activeVariables])\n  const headersLines = React.useMemo(() => activeHeaders.split('\\n'), [activeHeaders])\n  const formattedResponseString = React.useMemo(() => JSON.stringify(responseJson, null, 2), [responseJson])\n  const responseLines = React.useMemo(() => formattedResponseString.split('\\n'), [formattedResponseString])\n\n  const detectedOperation = React.useMemo(() => {\n    const q = activeQuery.trim()\n    if (q.startsWith('mutation')) return { type: 'mutation', color: 'bg-warning/10 text-warning border-warning/30' }\n    if (q.startsWith('subscription'))\n      return {\n        type: 'subscription',\n        color: 'bg-chart-1/10 text-chart-1 border-chart-1/30',\n      }\n    return { type: 'query', color: 'bg-info/10 text-info border-info/30' }\n  }, [activeQuery])\n\n  const isVariablesValidJson = React.useMemo(() => {\n    try {\n      JSON.parse(activeVariables)\n      return true\n    } catch {\n      return false\n    }\n  }, [activeVariables])\n\n  const handlePrettify = () => {\n    setActiveQuery(prettifyGraphql(activeQuery))\n    if (isVariablesValidJson) {\n      try {\n        setActiveVariables(JSON.stringify(JSON.parse(activeVariables), null, 2))\n      } catch {\n        // Keep as-is\n      }\n    }\n  }\n\n  const runQuery = () => {\n    if (isLoading) return\n    setIsLoading(true)\n\n    setTimeout(() => {\n      const randMs = Math.floor(Math.random() * 40) + 35\n      setResponseLatency(`${randMs}ms`)\n\n      const trimmed = activeQuery.trim()\n      if (trimmed.includes('createOrder') || trimmed.includes('mutation')) {\n        setResponseJson(presets[2].response)\n        setResponseSize(presets[2].size)\n        setResponseStatus('200 OK')\n      } else if (trimmed.includes('orderStatusUpdated') || trimmed.includes('subscription')) {\n        setResponseJson(presets[3].response)\n        setResponseSize(presets[3].size)\n        setResponseStatus('200 OK · SSE Stream')\n      } else if (trimmed.includes('users') || trimmed.includes('ListUsers')) {\n        setResponseJson(presets[1].response)\n        setResponseSize(presets[1].size)\n        setResponseStatus('200 OK')\n      } else {\n        setResponseJson(presets[0].response)\n        setResponseSize(presets[0].size)\n        setResponseStatus('200 OK')\n      }\n\n      setIsLoading(false)\n    }, 260)\n  }\n\n  const loadPreset = (preset: QueryPreset) => {\n    setActiveQuery(preset.query)\n    setActiveVariables(preset.variables)\n    setResponseJson(preset.response)\n    setResponseLatency(preset.latency)\n    setResponseSize(preset.size)\n    setShowHistoryDropdown(false)\n  }\n\n  const loadFieldQuery = (field: SchemaField) => {\n    setActiveQuery(field.sampleQuery)\n    setActiveVariables(field.sampleVariables)\n  }\n\n  const copyResponse = () => {\n    navigator.clipboard.writeText(formattedResponseString)\n    setCopiedResponse(true)\n    setTimeout(() => {\n      setCopiedResponse(false)\n    }, 2000)\n  }\n\n  return (\n    <Card\n      data-slot=\"graphql-query-explorer\"\n      className={cn(\n        'border-border bg-card text-card-foreground flex min-h-[720px] flex-col overflow-hidden rounded-xl border shadow-xs',\n        className,\n      )}\n    >\n      {/* TOP TOOLBAR */}\n      <header className=\"border-border bg-muted/40 flex flex-wrap items-center justify-between gap-3 border-b px-4 py-3\">\n        {/* Left: Endpoint & Method & Schema Badge */}\n        <div className=\"flex flex-wrap items-center gap-2.5\">\n          <Badge\n            variant=\"outline\"\n            className=\"border-border bg-background font-mono text-xs font-semibold tracking-wider\"\n          >\n            POST\n          </Badge>\n\n          <div className=\"border-border bg-background flex h-8 items-center gap-2 rounded-md border px-3 text-xs shadow-xs\">\n            <Globe className=\"text-muted-foreground size-3.5\" />\n            <input\n              value={endpointUrl}\n              onChange={(e) => setEndpointUrl(e.target.value)}\n              type=\"text\"\n              className=\"text-foreground w-64 bg-transparent font-mono text-xs focus:outline-none\"\n              placeholder=\"https://api.example.com/graphql\"\n            />\n          </div>\n\n          <Badge variant=\"secondary\" className=\"gap-1.5 py-1 font-mono text-xs font-normal\">\n            <span className=\"bg-success size-1.5 animate-pulse rounded-full\" />\n            Schema v2.4 · 48 Types\n          </Badge>\n        </div>\n\n        {/* Right: Action Buttons */}\n        <div className=\"flex flex-wrap items-center gap-2\">\n          <Button\n            variant=\"outline\"\n            size=\"sm\"\n            className=\"h-8 gap-1.5 text-xs\"\n            title=\"Format query (Shift + Option + F)\"\n            onClick={handlePrettify}\n          >\n            <AlignLeft className=\"size-3.5\" />\n            Prettify\n          </Button>\n\n          {/* History Menu Toggle */}\n          <div className=\"relative\">\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              className=\"h-8 gap-1.5 text-xs\"\n              onClick={() => setShowHistoryDropdown(!showHistoryDropdown)}\n            >\n              <History className=\"size-3.5\" />\n              History\n              <Badge variant=\"secondary\" className=\"ml-0.5 h-4 px-1 font-mono text-xs\">\n                {presets.length}\n              </Badge>\n            </Button>\n\n            {/* History Dropdown Card */}\n            {showHistoryDropdown && (\n              <div className=\"border-border bg-popover text-popover-foreground absolute right-0 z-50 mt-2 w-80 rounded-lg border p-2 text-xs shadow-md\">\n                <div className=\"border-border text-muted-foreground flex items-center justify-between gap-x-2 border-b px-2 py-1.5 font-medium\">\n                  <span>Recent Executions</span>\n                  <span className=\"font-mono text-xs\">Saved Stubs</span>\n                </div>\n                <div className=\"mt-1 max-h-60 space-y-1 overflow-y-auto\">\n                  {presets.map((preset) => (\n                    <button\n                      key={preset.id}\n                      className=\"hover:bg-muted focus:bg-muted flex w-full flex-col gap-0.5 rounded-md p-2 text-left transition-colors\"\n                      onClick={() => loadPreset(preset)}\n                    >\n                      <div className=\"flex items-center justify-between gap-x-2\">\n                        <span className=\"text-foreground font-mono font-medium\">{preset.name}</span>\n                        <Badge variant=\"outline\" className=\"font-mono text-xs font-normal\">\n                          {preset.latency}\n                        </Badge>\n                      </div>\n                      <div className=\"text-muted-foreground flex flex-wrap items-center gap-2 font-mono text-xs\">\n                        <span className=\"text-primary font-semibold uppercase\">{preset.operationType}</span>\n                        <span>·</span>\n                        <span>{preset.timestamp}</span>\n                      </div>\n                    </button>\n                  ))}\n                </div>\n              </div>\n            )}\n          </div>\n\n          {/* Run Query Primary Action */}\n          <Button\n            variant=\"default\"\n            size=\"sm\"\n            className=\"bg-primary text-primary-foreground hover:bg-primary/90 h-8 gap-2 text-xs font-semibold shadow-xs\"\n            disabled={isLoading}\n            onClick={runQuery}\n          >\n            {isLoading ? <Loader2 className=\"size-3.5 animate-spin\" /> : <Play className=\"size-3.5 fill-current\" />}\n            Run Query\n            <kbd className=\"border-primary-foreground/30 bg-primary-foreground/15 hidden rounded border px-1 py-0.5 font-mono text-xs font-normal sm:inline-block\">\n              ⌘↵\n            </kbd>\n          </Button>\n        </div>\n      </header>\n\n      {/* 3-COLUMN STUDIO LAYOUT */}\n      <div className=\"divide-border grid flex-1 grid-cols-1 divide-y overflow-hidden lg:grid-cols-12 lg:divide-x lg:divide-y-0\">\n        {/* COLUMN 1: SCHEMA DOCUMENTATION SIDEBAR (lg:col-span-3) */}\n        <GraphqlSchemaSidebar onLoadField={loadFieldQuery} />\n\n        {/* COLUMN 2: CENTER QUERY & VARIABLES EDITOR (lg:col-span-5) */}\n        <main className=\"bg-card flex flex-col overflow-hidden lg:col-span-5\">\n          {/* Query Toolbar */}\n          <div className=\"border-border bg-muted/20 flex items-center justify-between gap-x-2 border-b px-3 py-2\">\n            <div className=\"flex flex-wrap items-center gap-2\">\n              <FileCode className=\"text-primary size-4\" />\n              <span className=\"text-foreground font-mono text-xs font-semibold\">Query.graphql</span>\n              <Badge variant=\"outline\" className={cn('font-mono text-xs uppercase', detectedOperation.color)}>\n                {detectedOperation.type}\n              </Badge>\n            </div>\n\n            <div className=\"flex flex-wrap items-center gap-2\">\n              <span className=\"text-muted-foreground font-mono text-xs\">\n                {queryLines.length} lines · {activeQuery.length} chars\n              </span>\n              <div className=\"border-border bg-muted/60 flex items-center rounded-md border p-0.5\">\n                <button\n                  className={cn(\n                    'min-h-6 rounded px-2 py-0.5 text-xs font-medium transition-colors',\n                    editorMode === 'edit'\n                      ? 'bg-background text-foreground shadow-xs'\n                      : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setEditorMode('edit')}\n                >\n                  Edit\n                </button>\n                <button\n                  className={cn(\n                    'min-h-6 rounded px-2 py-0.5 text-xs font-medium transition-colors',\n                    editorMode === 'preview'\n                      ? 'bg-background text-foreground shadow-xs'\n                      : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setEditorMode('preview')}\n                >\n                  Preview\n                </button>\n              </div>\n            </div>\n          </div>\n\n          {/* Query Editor Body with Line Numbers */}\n          <div className=\"relative flex min-h-[260px] flex-1 overflow-hidden\">\n            {/* Line Numbers Gutter */}\n            <div className=\"border-border/60 bg-muted/20 text-muted-foreground/50 w-10 shrink-0 overflow-hidden border-r py-3 pr-2 text-right font-mono text-xs leading-relaxed select-none\">\n              {queryLines.map((_, idx) => (\n                <div key={idx}>{idx + 1}</div>\n              ))}\n            </div>\n\n            {/* Code Area: Editable or Syntax Preview */}\n            <div className=\"bg-background/50 flex-1 overflow-auto\">\n              {editorMode === 'edit' ? (\n                <textarea\n                  value={activeQuery}\n                  onChange={(e) => setActiveQuery(e.target.value)}\n                  spellCheck={false}\n                  className=\"text-foreground h-full w-full resize-none bg-transparent p-3 font-mono text-xs leading-relaxed focus:outline-none\"\n                  placeholder=\"# Write GraphQL query or mutation here...\"\n                />\n              ) : (\n                <div className=\"space-y-0.5 p-3 font-mono text-xs leading-relaxed\">\n                  {queryLines.map((line, idx) => (\n                    <div\n                      key={idx}\n                      className=\"whitespace-pre\"\n                      dangerouslySetInnerHTML={{ __html: highlightGraphqlLine(line) }}\n                    />\n                  ))}\n                </div>\n              )}\n            </div>\n          </div>\n\n          {/* COLLAPSIBLE BOTTOM PANE: VARIABLES / HEADERS */}\n          <div className=\"border-border bg-muted/10 flex flex-col border-t\">\n            {/* Pane Header */}\n            <div className=\"border-border bg-muted/30 flex items-center justify-between gap-x-2 border-b px-3 py-1.5 text-xs\">\n              <div className=\"flex items-center gap-3\">\n                <button\n                  className={cn(\n                    'font-mono font-medium transition-colors',\n                    activeCenterTab === 'variables' ? 'text-foreground' : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setActiveCenterTab('variables')}\n                >\n                  {'{ }'} Query Variables\n                </button>\n                <span className=\"text-border\">|</span>\n                <button\n                  className={cn(\n                    'font-mono font-medium transition-colors',\n                    activeCenterTab === 'headers' ? 'text-foreground' : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setActiveCenterTab('headers')}\n                >\n                  HTTP Headers (2)\n                </button>\n              </div>\n\n              <div className=\"flex flex-wrap items-center gap-2\">\n                {activeCenterTab === 'variables' && (\n                  <Badge\n                    variant=\"outline\"\n                    className={cn(\n                      'font-mono text-xs',\n                      isVariablesValidJson\n                        ? 'border-success/30 text-success'\n                        : 'border-destructive/30 text-destructive',\n                    )}\n                  >\n                    {isVariablesValidJson ? 'Valid JSON' : 'Invalid JSON'}\n                  </Badge>\n                )}\n\n                <button\n                  className=\"text-muted-foreground hover:text-foreground min-h-6 p-0.5 transition-colors\"\n                  title={isVariablesCollapsed ? 'Expand pane' : 'Collapse pane'}\n                  onClick={() => setIsVariablesCollapsed(!isVariablesCollapsed)}\n                >\n                  {isVariablesCollapsed ? <ChevronUp className=\"size-3.5\" /> : <ChevronDown className=\"size-3.5\" />}\n                </button>\n              </div>\n            </div>\n\n            {/* Pane Content */}\n            {!isVariablesCollapsed && (\n              <div className=\"bg-background/50 relative flex h-36 min-h-[140px] overflow-hidden\">\n                {activeCenterTab === 'variables' ? (\n                  <>\n                    <div className=\"border-border/60 bg-muted/20 text-muted-foreground/50 w-8 shrink-0 overflow-hidden border-r py-2 pr-2 text-right font-mono text-xs leading-relaxed select-none\">\n                      {variableLines.map((_, idx) => (\n                        <div key={idx}>{idx + 1}</div>\n                      ))}\n                    </div>\n                    <textarea\n                      value={activeVariables}\n                      onChange={(e) => setActiveVariables(e.target.value)}\n                      spellCheck={false}\n                      className=\"text-foreground h-full w-full resize-none bg-transparent p-2 font-mono text-xs leading-relaxed focus:outline-none\"\n                      placeholder=\"{}\"\n                    />\n                  </>\n                ) : (\n                  <>\n                    <div className=\"border-border/60 bg-muted/20 text-muted-foreground/50 w-8 shrink-0 overflow-hidden border-r py-2 pr-2 text-right font-mono text-xs leading-relaxed select-none\">\n                      {headersLines.map((_, idx) => (\n                        <div key={idx}>{idx + 1}</div>\n                      ))}\n                    </div>\n                    <textarea\n                      value={activeHeaders}\n                      onChange={(e) => setActiveHeaders(e.target.value)}\n                      spellCheck={false}\n                      className=\"text-foreground h-full w-full resize-none bg-transparent p-2 font-mono text-xs leading-relaxed focus:outline-none\"\n                    />\n                  </>\n                )}\n              </div>\n            )}\n          </div>\n        </main>\n\n        {/* COLUMN 3: RIGHT RESPONSE PANEL (lg:col-span-4) */}\n        <section className=\"bg-muted/10 flex flex-col overflow-hidden lg:col-span-4\">\n          {/* Response Header */}\n          <div className=\"border-border bg-muted/30 flex items-center justify-between gap-x-2 border-b px-3 py-2\">\n            <div className=\"flex flex-wrap items-center gap-2\">\n              <Badge\n                variant=\"outline\"\n                className=\"border-success/30 bg-success/10 text-success gap-1.5 font-mono text-xs font-semibold\"\n              >\n                <span className=\"bg-success size-1.5 rounded-full\" />\n                {responseStatus}\n              </Badge>\n\n              <span className=\"text-muted-foreground flex items-center gap-1 font-mono text-xs\">\n                <Zap className=\"text-warning size-3\" />\n                {responseLatency}\n              </span>\n\n              <span className=\"text-muted-foreground font-mono text-xs\">{responseSize}</span>\n            </div>\n\n            <Button variant=\"ghost\" size=\"sm\" className=\"h-7 gap-1 px-2 text-xs\" onClick={copyResponse}>\n              {copiedResponse ? <Check className=\"text-success size-3\" /> : <Copy className=\"size-3\" />}\n              <span>{copiedResponse ? 'Copied' : 'Copy'}</span>\n            </Button>\n          </div>\n\n          {/* Response View Tabs */}\n          <div className=\"border-border bg-muted/20 flex items-center gap-1 border-b px-3 py-1\">\n            <button\n              className={cn(\n                'min-h-6 rounded px-2 py-1 font-mono text-xs font-medium transition-colors',\n                activeResponseTab === 'response'\n                  ? 'bg-background text-foreground shadow-xs'\n                  : 'text-muted-foreground hover:text-foreground',\n              )}\n              onClick={() => setActiveResponseTab('response')}\n            >\n              Response JSON\n            </button>\n            <button\n              className={cn(\n                'min-h-6 rounded px-2 py-1 font-mono text-xs font-medium transition-colors',\n                activeResponseTab === 'tracing'\n                  ? 'bg-background text-foreground shadow-xs'\n                  : 'text-muted-foreground hover:text-foreground',\n              )}\n              onClick={() => setActiveResponseTab('tracing')}\n            >\n              Tracing\n            </button>\n            <button\n              className={cn(\n                'min-h-6 rounded px-2 py-1 font-mono text-xs font-medium transition-colors',\n                activeResponseTab === 'headers'\n                  ? 'bg-background text-foreground shadow-xs'\n                  : 'text-muted-foreground hover:text-foreground',\n              )}\n              onClick={() => setActiveResponseTab('headers')}\n            >\n              Headers\n            </button>\n          </div>\n\n          {/* Loading Indicator */}\n          {isLoading ? (\n            <div className=\"flex flex-1 flex-col items-center justify-center gap-3 p-6 text-center\">\n              <Loader2 className=\"text-primary size-6 animate-spin\" />\n              <div className=\"space-y-1\">\n                <p className=\"text-foreground font-mono text-xs font-medium\">Executing GraphQL Operation...</p>\n                <p className=\"text-muted-foreground font-mono text-xs\">{endpointUrl}</p>\n              </div>\n            </div>\n          ) : activeResponseTab === 'response' ? (\n            /* Response Body: Tab 1 (JSON Response) */\n            <div className=\"relative flex flex-1 overflow-auto bg-neutral-950 text-neutral-100 dark:bg-neutral-950\">\n              {/* Gutter */}\n              <div className=\"w-10 shrink-0 overflow-hidden border-r border-neutral-800 bg-neutral-900/50 py-3 pr-2 text-right font-mono text-xs leading-relaxed text-neutral-500 select-none\">\n                {responseLines.map((_, idx) => (\n                  <div key={idx}>{idx + 1}</div>\n                ))}\n              </div>\n\n              {/* Colorized JSON Code */}\n              <div className=\"flex-1 overflow-auto p-3 font-mono text-xs leading-relaxed\">\n                {responseLines.map((line, idx) => (\n                  <div\n                    key={idx}\n                    className=\"font-mono whitespace-pre\"\n                    dangerouslySetInnerHTML={{ __html: highlightJsonLine(line) }}\n                  />\n                ))}\n              </div>\n            </div>\n          ) : activeResponseTab === 'tracing' ? (\n            <GraphqlTracingPanel latency={responseLatency} />\n          ) : (\n            /* Response Body: Tab 3 (HTTP Response Headers) */\n            <div className=\"flex-1 space-y-2 overflow-y-auto p-3 font-mono text-xs\">\n              <div className=\"border-border bg-card space-y-2 rounded-lg border p-3\">\n                <div className=\"border-border/50 flex justify-between border-b pb-1.5\">\n                  <span className=\"text-muted-foreground\">content-type:</span>\n                  <span className=\"text-foreground font-medium\">application/graphql-response+json; charset=utf-8</span>\n                </div>\n                <div className=\"border-border/50 flex justify-between border-b pb-1.5\">\n                  <span className=\"text-muted-foreground\">cache-control:</span>\n                  <span className=\"text-foreground font-medium\">max-age=0, private, must-revalidate</span>\n                </div>\n                <div className=\"border-border/50 flex justify-between border-b pb-1.5\">\n                  <span className=\"text-muted-foreground\">x-request-id:</span>\n                  <span className=\"text-foreground font-medium\">req_01hx8921a9vnm8</span>\n                </div>\n                <div className=\"flex justify-between\">\n                  <span className=\"text-muted-foreground\">server-timing:</span>\n                  <span className=\"text-foreground font-medium\">graphql;dur=64.1</span>\n                </div>\n              </div>\n            </div>\n          )}\n        </section>\n      </div>\n    </Card>\n  )\n}\n\nexport default GraphqlQueryExplorer\n",
      "type": "registry:block",
      "target": "~/components/blocks/graphql-query-explorer/GraphqlQueryExplorer.tsx"
    },
    {
      "path": "packages/registry-react/blocks/graphql-query-explorer/GraphqlSchemaSidebar.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { ChevronDown, ChevronRight, Database, Search } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Input } from '@/components/ui/input'\nimport { cn } from '@/lib/utils'\nimport { type RootType, type SchemaField } from './graphql-query-explorer-types'\n\nconst schemaRoots: RootType[] = [\n  {\n    name: 'Query',\n    color: 'text-info',\n    badgeVariant: 'default',\n    fields: [\n      {\n        name: 'customer',\n        args: 'id: ID!',\n        returnType: 'Customer',\n        description: 'Fetches verified customer account, active SaaS subscriptions, and verified billing profile.',\n        sampleQuery: `query GetCustomerProfile($id: ID!) {\\n  customer(id: $id) {\\n    id\\n    name\\n    email\\n    subscriptions { id status plan }\\n  }\\n}`,\n        sampleVariables: `{\\n  \"id\": \"cust_8492\"\\n}`,\n      },\n      {\n        name: 'users',\n        args: 'limit: Int, offset: Int',\n        returnType: '[User!]!',\n        description: 'Returns paginated workspace members with security roles and activity status flags.',\n        sampleQuery: `query ListUsers($limit: Int, $offset: Int) {\\n  users(limit: $limit, offset: $offset) {\\n    id\\n    fullName\\n    email\\n    role\\n  }\\n}`,\n        sampleVariables: `{\\n  \"limit\": 10,\\n  \"offset\": 0\\n}`,\n      },\n      {\n        name: 'userById',\n        args: 'id: ID!',\n        returnType: 'User',\n        description: 'Look up specific team member by their unique UUID identifier.',\n        sampleQuery: `query GetUser($id: ID!) {\\n  userById(id: $id) {\\n    id\\n    fullName\\n    email\\n    role\\n    isVerified\\n  }\\n}`,\n        sampleVariables: `{\\n  \"id\": \"usr_9011\"\\n}`,\n      },\n      {\n        name: 'products',\n        args: 'category: String, inStock: Boolean',\n        returnType: '[Product!]!',\n        description: 'Catalog items inventory with real-time stock levels and tiered price book.',\n        sampleQuery: `query GetProducts($category: String) {\\n  products(category: $category) {\\n    id\\n    title\\n    price\\n    inventoryCount\\n  }\\n}`,\n        sampleVariables: `{\\n  \"category\": \"developer-tools\"\\n}`,\n      },\n      {\n        name: 'orders',\n        args: 'status: OrderStatus, limit: Int',\n        returnType: '[Order!]!',\n        description: 'Historical and in-flight purchase orders with settlement metadata.',\n        sampleQuery: `query GetOrders($status: OrderStatus) {\\n  orders(status: $status) {\\n    id\\n    status\\n    totalAmount\\n    createdAt\\n  }\\n}`,\n        sampleVariables: `{\\n  \"status\": \"COMPLETED\"\\n}`,\n      },\n      {\n        name: 'organization',\n        args: 'slug: String!',\n        returnType: 'Organization',\n        description: 'Retrieve tenant workspace configurations, member limits, and billing tier.',\n        sampleQuery: `query GetOrg($slug: String!) {\\n  organization(slug: $slug) {\\n    id\\n    name\\n    slug\\n    memberCount\\n  }\\n}`,\n        sampleVariables: `{\\n  \"slug\": \"acme-corp\"\\n}`,\n      },\n    ],\n  },\n  {\n    name: 'Mutation',\n    color: 'text-warning',\n    badgeVariant: 'secondary',\n    fields: [\n      {\n        name: 'createOrder',\n        args: 'input: CreateOrderInput!',\n        returnType: 'OrderPayload!',\n        description: 'Creates new purchase order, holds inventory reservations, and emits payment intent.',\n        sampleQuery: `mutation CreateOrder($input: CreateOrderInput!) {\\n  createOrder(input: $input) {\\n    order { id status totalAmount }\\n    clientSecret\\n  }\\n}`,\n        sampleVariables: `{\\n  \"input\": {\\n    \"customerId\": \"cust_8492\",\\n    \"items\": [{ \"sku\": \"SKU_01\", \"quantity\": 1, \"price\": 149.00 }]\\n  }\\n}`,\n      },\n      {\n        name: 'updateCustomer',\n        args: 'id: ID!, input: CustomerInput!',\n        returnType: 'Customer!',\n        description: 'Updates customer profile attributes and notification preferences.',\n        sampleQuery: `mutation UpdateCustomer($id: ID!, $input: CustomerInput!) {\\n  updateCustomer(id: $id, input: $input) {\\n    id\\n    name\\n    email\\n  }\\n}`,\n        sampleVariables: `{\\n  \"id\": \"cust_8492\",\\n  \"input\": { \"name\": \"Sarah Jenkins\" }\\n}`,\n      },\n      {\n        name: 'cancelSubscription',\n        args: 'id: ID!, reason: String',\n        returnType: 'SubscriptionResult!',\n        description: 'Immediately pauses or schedules cancellation for recurring billing plan.',\n        sampleQuery: `mutation CancelSub($id: ID!, $reason: String) {\\n  cancelSubscription(id: $id, reason: $reason) {\\n    id\\n    status\\n    effectiveDate\\n  }\\n}`,\n        sampleVariables: `{\\n  \"id\": \"sub_4410\",\\n  \"reason\": \"Upgraded to Enterprise annual\"\\n}`,\n      },\n      {\n        name: 'rotateApiKey',\n        args: 'keyId: ID!',\n        returnType: 'ApiKeyRotationPayload!',\n        description: 'Invalidates existing API secret and provisions new machine token.',\n        sampleQuery: `mutation RotateKey($keyId: ID!) {\\n  rotateApiKey(keyId: $keyId) {\\n    keyId\\n    secretToken\\n    expiresAt\\n  }\\n}`,\n        sampleVariables: `{\\n  \"keyId\": \"key_live_9941\"\\n}`,\n      },\n    ],\n  },\n  {\n    name: 'Subscription',\n    color: 'text-chart-1',\n    badgeVariant: 'outline',\n    fields: [\n      {\n        name: 'orderStatusUpdated',\n        args: 'orderId: ID!',\n        returnType: 'OrderStatusEvent!',\n        description: 'Live push stream delivering order state transitions and logistics milestones.',\n        sampleQuery: `subscription WatchOrder($orderId: ID!) {\\n  orderStatusUpdated(orderId: $orderId) {\\n    orderId\\n    newStatus\\n    updatedAt\\n  }\\n}`,\n        sampleVariables: `{\\n  \"orderId\": \"ord_88201\"\\n}`,\n      },\n      {\n        name: 'userActivityStream',\n        args: 'channelId: ID!',\n        returnType: 'ActivityEvent!',\n        description: 'Workspace real-time collaboration telemetry and presence updates.',\n        sampleQuery: `subscription ActivityStream($channelId: ID!) {\\n  userActivityStream(channelId: $channelId) {\\n    userId\\n    action\\n    timestamp\\n  }\\n}`,\n        sampleVariables: `{\\n  \"channelId\": \"chan_engineering\"\\n}`,\n      },\n    ],\n  },\n]\n\nexport function GraphqlSchemaSidebar({ onLoadField }: { onLoadField: (field: SchemaField) => void }) {\n  const [schemaSearch, setSchemaSearch] = React.useState('')\n  const [selectedField, setSelectedField] = React.useState<SchemaField | null>(null)\n  const [expandedRoots, setExpandedRoots] = React.useState<Record<string, boolean>>({\n    Query: true,\n    Mutation: true,\n    Subscription: true,\n  })\n\n  const filteredSchemaRoots = React.useMemo(() => {\n    const query = schemaSearch.trim().toLowerCase()\n    if (!query) return schemaRoots\n\n    return schemaRoots\n      .map((root) => {\n        const matchingFields = root.fields.filter(\n          (f) =>\n            f.name.toLowerCase().includes(query) ||\n            f.returnType.toLowerCase().includes(query) ||\n            (f.args && f.args.toLowerCase().includes(query)) ||\n            f.description.toLowerCase().includes(query),\n        )\n        return {\n          ...root,\n          fields: matchingFields,\n        }\n      })\n      .filter((root) => root.fields.length > 0)\n  }, [schemaSearch])\n\n  const toggleRoot = (name: string) => {\n    setExpandedRoots((prev) => ({ ...prev, [name]: !prev[name] }))\n  }\n\n  const handleSelectField = (field: SchemaField) => {\n    setSelectedField(field)\n    onLoadField(field)\n  }\n\n  return (\n    <>\n      {/* COLUMN 1: SCHEMA DOCUMENTATION SIDEBAR (lg:col-span-3) */}\n      <aside className=\"bg-muted/15 flex flex-col overflow-hidden lg:col-span-3\">\n        {/* Sidebar Header */}\n        <div className=\"border-border bg-muted/30 flex items-center justify-between gap-x-2 border-b px-3 py-2.5\">\n          <div className=\"flex items-center gap-1.5 text-xs font-semibold\">\n            <Database className=\"text-primary size-3.5\" />\n            <span>Schema Explorer</span>\n          </div>\n          <Badge variant=\"outline\" className=\"font-mono text-xs\">\n            v2.4\n          </Badge>\n        </div>\n\n        {/* Search Types Input */}\n        <div className=\"border-border border-b p-2.5\">\n          <div className=\"relative\">\n            <Search className=\"text-muted-foreground absolute top-2.5 left-2.5 size-3.5\" />\n            <Input\n              value={schemaSearch}\n              onChange={(e) => setSchemaSearch(e.target.value)}\n              type=\"text\"\n              placeholder=\"Search types & fields...\"\n              className=\"h-8 pl-8 font-mono text-xs\"\n            />\n          </div>\n        </div>\n\n        {/* Root Types & Field Tree */}\n        <div className=\"flex-1 space-y-3 overflow-y-auto p-2.5\">\n          {filteredSchemaRoots.map((root) => (\n            <div key={root.name} className=\"space-y-1\">\n              {/* Root Type Toggle */}\n              <button\n                className=\"hover:bg-muted/60 flex w-full items-center justify-between rounded-md px-2 py-1.5 text-left text-xs font-semibold transition-colors\"\n                onClick={() => toggleRoot(root.name)}\n              >\n                <div className=\"flex items-center gap-1.5\">\n                  {expandedRoots[root.name] ? (\n                    <ChevronDown className=\"text-muted-foreground size-3.5\" />\n                  ) : (\n                    <ChevronRight className=\"text-muted-foreground size-3.5\" />\n                  )}\n                  <span className={root.color}>{root.name}</span>\n                </div>\n                <Badge variant=\"secondary\" className=\"font-mono text-xs font-normal\">\n                  {root.fields.length}\n                </Badge>\n              </button>\n\n              {/* Fields List */}\n              {expandedRoots[root.name] && (\n                <div className=\"border-border/70 ml-2 space-y-0.5 border-l pl-2\">\n                  {root.fields.map((field) => (\n                    <button\n                      key={field.name}\n                      className={cn(\n                        'hover:bg-muted focus:bg-muted group flex w-full flex-col gap-0.5 rounded px-2 py-1.5 text-left transition-colors',\n                        selectedField?.name === field.name && 'bg-muted/90 ring-border ring-1',\n                      )}\n                      onClick={() => handleSelectField(field)}\n                    >\n                      <div className=\"flex items-center justify-between gap-x-2\">\n                        <span className=\"text-foreground group-hover:text-primary font-mono text-xs font-medium transition-colors\">\n                          {field.name}\n                        </span>\n                        <span className=\"text-muted-foreground font-mono text-xs\">{field.returnType}</span>\n                      </div>\n                      {field.args && (\n                        <div className=\"text-muted-foreground truncate font-mono text-xs\">({field.args})</div>\n                      )}\n                    </button>\n                  ))}\n                </div>\n              )}\n            </div>\n          ))}\n        </div>\n\n        {/* Selected Field Documentation Preview */}\n        {selectedField && (\n          <div className=\"border-border bg-card/60 border-t p-3 text-xs\">\n            <div className=\"flex items-center justify-between gap-x-2\">\n              <span className=\"text-foreground font-mono font-semibold\">{selectedField.name}</span>\n              <Badge variant=\"secondary\" className=\"font-mono text-xs\">\n                {selectedField.returnType}\n              </Badge>\n            </div>\n            <p className=\"text-muted-foreground mt-1.5 text-xs leading-normal\">{selectedField.description}</p>\n            {selectedField.args && (\n              <div className=\"border-border bg-muted/40 mt-2 rounded border p-1.5 font-mono text-xs\">\n                <span className=\"text-muted-foreground\">Args: </span>\n                <span className=\"text-foreground font-medium\">{selectedField.args}</span>\n              </div>\n            )}\n          </div>\n        )}\n      </aside>\n    </>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/graphql-query-explorer/GraphqlSchemaSidebar.tsx"
    },
    {
      "path": "packages/registry-react/blocks/graphql-query-explorer/GraphqlTracingPanel.tsx",
      "content": "'use client'\n\nimport { Badge } from '@/components/ui/badge'\nimport { type ResolverTrace } from './graphql-query-explorer-types'\n\nconst traces: ResolverTrace[] = [\n  {\n    path: 'Query.customer',\n    parentType: 'Query',\n    fieldName: 'customer',\n    returnType: 'Customer',\n    durationMs: 48.2,\n    percentage: 75,\n  },\n  {\n    path: 'Customer.subscriptions',\n    parentType: 'Customer',\n    fieldName: 'subscriptions',\n    returnType: '[Subscription!]!',\n    durationMs: 14.9,\n    percentage: 23,\n  },\n  {\n    path: 'Customer.billingAddress',\n    parentType: 'Customer',\n    fieldName: 'billingAddress',\n    returnType: 'BillingAddress',\n    durationMs: 1.0,\n    percentage: 2,\n  },\n]\n\nexport function GraphqlTracingPanel({ latency }: { latency: string }) {\n  return (\n    <>\n      /* Response Body: Tab 2 (Tracing Waterfall) */\n      <div className=\"flex-1 space-y-3 overflow-y-auto p-4\">\n        <div className=\"border-border bg-card flex items-center justify-between gap-x-2 rounded-lg border p-3\">\n          <div>\n            <span className=\"text-muted-foreground text-xs\">Total Duration</span>\n            <p className=\"text-foreground font-mono text-base font-bold\">{latency}</p>\n          </div>\n          <Badge variant=\"secondary\" className=\"font-mono text-xs\">\n            Apollo Tracing v1\n          </Badge>\n        </div>\n\n        <div className=\"space-y-2\">\n          <span className=\"text-muted-foreground font-mono text-xs font-medium\">Resolver Execution Times</span>\n          <div className=\"space-y-2\">\n            {traces.map((trace) => (\n              <div key={trace.path} className=\"border-border bg-card space-y-1.5 rounded-lg border p-2.5 text-xs\">\n                <div className=\"flex items-center justify-between gap-x-2\">\n                  <span className=\"text-foreground font-mono font-semibold\">{trace.path}</span>\n                  <span className=\"text-muted-foreground font-mono\">{trace.durationMs}ms</span>\n                </div>\n                <div className=\"bg-muted h-1.5 w-full overflow-hidden rounded-full\">\n                  <div className=\"bg-primary h-full rounded-full\" style={{ width: `${trace.percentage}%` }} />\n                </div>\n                <div className=\"text-muted-foreground flex justify-between font-mono text-xs\">\n                  <span>Type: {trace.returnType}</span>\n                  <span>{trace.percentage}% of query</span>\n                </div>\n              </div>\n            ))}\n          </div>\n        </div>\n      </div>\n    </>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/graphql-query-explorer/GraphqlTracingPanel.tsx"
    },
    {
      "path": "packages/registry-react/blocks/graphql-query-explorer/graphql-query-explorer-types.ts",
      "content": "export interface SchemaField {\n  name: string\n  args?: string\n  returnType: string\n  description: string\n  sampleQuery: string\n  sampleVariables: string\n}\n\nexport interface RootType {\n  name: 'Query' | 'Mutation' | 'Subscription'\n  color: string\n  badgeVariant: 'default' | 'secondary' | 'outline'\n  fields: SchemaField[]\n}\n\nexport interface QueryPreset {\n  id: string\n  name: string\n  operationType: 'query' | 'mutation' | 'subscription'\n  query: string\n  variables: string\n  response: Record<string, unknown>\n  latency: string\n  size: string\n  timestamp: string\n}\n\nexport interface ResolverTrace {\n  path: string\n  parentType: string\n  fieldName: string\n  returnType: string\n  durationMs: number\n  percentage: number\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/graphql-query-explorer/graphql-query-explorer-types.ts"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json"
  ],
  "description": "Apollo and GraphiQL style GraphQL query builder and response inspector with schema documentation sidebar, syntax-highlighted query & variables editor, query history presets, execution tracing, and formatted JSON response viewer.",
  "categories": [
    "devops",
    "app"
  ]
}