{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "core-diagnostic-panel",
  "type": "registry:ui",
  "title": "Diagnostic Panel",
  "description": "The eleven-tab developer view of a running plugin: Overview, Host, Transport/Clock, MIDI, Audio, Parameters, Presets/State, Events, Stimulus, Performance and Package. Controlled and presentational — it takes a DiagnosticSession and its snapshot and renders them, owning no bridge and opening no feed, so it embeds equally in a drawer, a dev-runner pane or a docs page. Its one editorial rule is that every value either comes from the snapshot or renders as an explicit Unreported cell: there is no `?? 0` anywhere, because a host that never reported its latency is not a host with zero latency, and a meter frame that never arrived is not silence. The stereo verdict consults per-channel RMS before correlation for the same reason — a silent pair correlates at exactly 1.0, and would otherwise be reported as perfect mono. The Overview leads with a status strip whose health verdict overrides a host's own claim when the feeds it promised have gone silent, because a dead feed is a broken host bridge however healthy the DSP says it is; Copy report puts a ten-line plain-text summary on the clipboard ahead of the JSON, because that is what gets pasted into chat. Nothing costs a frame while the panel is closed: the four canvas viewers share one animation frame that is never scheduled unless the Audio tab is visible, each tab is memoised over the slice of the snapshot it reads, and tables past 200 rows render only the band you can see.",
  "dependencies": [
    "@webgpu/types",
    "maruaudio@>=0.0.3 <0.1.0"
  ],
  "registryDependencies": [
    "https://pluginui.com/r/core-goniometer.json",
    "https://pluginui.com/r/core-level-meter.json",
    "https://pluginui.com/r/core-oscilloscope.json",
    "https://pluginui.com/r/core-piano-keyboard.json",
    "https://pluginui.com/r/core-spectrum.json"
  ],
  "files": [
    {
      "path": "components/ui/diagnostic-panel.tsx",
      "content": "/**\n * Source: https://maru.audio/ui-kit/diagnostic-panel\n * Copyright © [Maru](https://maru.audio)\n *\n * Maru UI Kit — https://maru.audio/ui-kit\n *\n * Installed from the Maru UI registry. This file is yours now: edit it\n * freely, it will not be overwritten unless you re-run the add command.\n *\n * Keep this item’s companion files and CSS imports together. Dependencies\n * declared by the registry are installed with the source.\n */\n/**\n * `DiagnosticPanel` — the developer view of a `DiagnosticSession`.\n *\n * Controlled and presentational: it takes a snapshot and a session and renders\n * them. It owns no bridge, opens no feed and decides nothing about visibility —\n * that is `DiagnosticOverlay`'s job, so the panel can also be embedded whole in\n * a dev-runner pane, a docs page or a test.\n *\n * The editorial rule the whole panel is built on: **every value either comes\n * from the snapshot or renders as `Unreported`.** There is no `?? 0`, no\n * `|| \"unknown\"` and no placeholder that could be mistaken for a measurement.\n * A host that reports nothing produces a panel full of \"Unreported\" cells,\n * which is the honest answer and an actionable one — it says the host is the\n * gap, not the plugin.\n *\n * ## What costs a frame, and what does not\n *\n * The snapshot changes up to 30 times a second while the panel is open, and a\n * naive panel re-renders all eleven tabs' worth of subtree on every one of\n * them. Three rules keep that bounded:\n *\n * 1. **Only the active tab is mounted.** A tab that is not on screen has no\n *    fiber, so a meters frame cannot re-render the Events table.\n * 2. **Each tab is a `memo` over the slice of the snapshot it actually\n *    reads** — see `diagnostic-tab-slices.ts`. A meters frame changes\n *    `snapshot.meters` and nothing else, so the Events tab's props are\n *    referentially unchanged and its memo holds even in the moment the user\n *    switches to it.\n * 3. **Canvas viewers share one animation frame** (`diagnostic-panel-raf.ts`),\n *    which is never scheduled while the panel is closed or the document\n *    hidden.\n *\n * Styling uses `control-theme`'s `token()` with inline styles and no Tailwind,\n * because this component ends up inside plugin webviews with no build step.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport type { CSSProperties } from \"react\"\nimport type {\n  DiagnosticSession,\n  DiagnosticSnapshot,\n} from \"maruaudio/ui/shared/maru/diagnostic-session\"\nimport type { AudioModuleLatencyPlan, ParamSchema } from \"maruaudio/ui/shared/maru/contracts\"\n\nimport { token } from \"maruaudio/ui/shared/theme\"\nimport { SR_ONLY, buttonStyle } from \"@/components/ui/diagnostic-panel-chrome\"\nimport {\n  DIAGNOSTIC_TAB_GLYPHS,\n  RAIL_ICON_MAX_WIDTH,\n  TIME_AGO_REFRESH_MS,\n  buildPlainTextSummary,\n  buildSummaryLine,\n  buildTimestampLabel,\n  overallHealth,\n  resolveDiagnosticTab,\n  visibleDiagnosticTabs,\n  type DiagnosticTabId,\n} from \"maruaudio/ui/shared/diagnostic-panel-core\"\nimport {\n  HostTab,\n  LatencyTab,\n  OverviewTab,\n  PackageTab,\n  ParametersTab,\n  PerformanceTab,\n  PresetsTab,\n  SamplerTab,\n  type ModuleFaceRuntimeStatusLike,\n} from \"@/components/ui/diagnostic-tabs-info\"\nimport {\n  AudioTab,\n  EventsTab,\n  MidiTab,\n  StimulusTab,\n  TransportTab,\n  writeClipboard,\n} from \"@/components/ui/diagnostic-tabs-live\"\nimport { toneColor } from \"@/components/ui/diagnostic-panel-chrome\"\n\nexport interface DiagnosticPanelProps {\n  readonly session: DiagnosticSession\n  readonly snapshot: DiagnosticSnapshot\n  /** Build-time graph topology; runtime totals still come from the snapshot. */\n  readonly latencyPlan?: AudioModuleLatencyPlan\n  /** Authored parameter contract supplied by the module host. */\n  readonly schema?: ParamSchema\n  /** Controlled tab. Omit to let the panel own its selection. */\n  readonly tab?: DiagnosticTabId\n  readonly onTabChange?: (tab: DiagnosticTabId) => void\n  /** Rendered in the header, e.g. the overlay's close button. */\n  readonly headerActions?: React.ReactNode\n  /**\n   * False while the panel is mounted but not visible — a collapsed drawer, a\n   * hidden pane. The shared animation frame is not scheduled at all when this\n   * is false, so a hidden panel costs nothing.\n   */\n  readonly live?: boolean\n  /**\n   * The face's own `runtimeStatus` (`module-face.ts`) — host-owned async load\n   * progress. It is a face prop, not a diagnostic feed, so the panel takes it\n   * from its embedder rather than from the snapshot; the Sampler tab is its\n   * only reader.\n   */\n  readonly runtimeStatus?: ModuleFaceRuntimeStatusLike\n  readonly className?: string\n  readonly style?: CSSProperties\n}\n\n/**\n * Measure the panel's own width so the rail can collapse to icons.\n *\n * A container query would be the right tool, but the panel ships as inline\n * styles into webviews with no stylesheet, so the measurement is explicit. The\n * observer is created inside an effect and the initial state is the wide case,\n * which is what a server render must produce — a collapsed rail in the HTML\n * would flash open on hydration.\n */\nfunction usePanelWidth(ref: React.RefObject<HTMLDivElement | null>): number | null {\n  const [width, setWidth] = useState<number | null>(null)\n  useEffect(() => {\n    const node = ref.current\n    if (!node || typeof ResizeObserver === \"undefined\") return\n    const observer = new ResizeObserver((entries) => {\n      const entry = entries[0]\n      if (entry) setWidth(entry.contentRect.width)\n    })\n    observer.observe(node)\n    setWidth(node.getBoundingClientRect().width)\n    return () => observer.disconnect()\n  }, [ref])\n  return width\n}\n\nexport function DiagnosticPanel({\n  session,\n  snapshot,\n  latencyPlan,\n  schema,\n  tab,\n  onTabChange,\n  headerActions,\n  live = true,\n  runtimeStatus,\n  className,\n  style,\n}: DiagnosticPanelProps) {\n  const [ownTab, setOwnTab] = useState<DiagnosticTabId>(\"overview\")\n  /* The Sampler tab exists only on a shell that declared a bank table, so the\n   * rail, the arrow-key ring and the fallback all read this rather than\n   * DIAGNOSTIC_TABS. A stored preference naming a now-hidden tab falls back to\n   * Overview instead of rendering a tab with no rail entry. */\n  const visibleTabs = useMemo(\n    () => visibleDiagnosticTabs(snapshot.banks, latencyPlan !== undefined),\n    [latencyPlan, snapshot.banks],\n  )\n  const requested = resolveDiagnosticTab(tab ?? ownTab)\n  const active = visibleTabs.some((entry) => entry.id === requested)\n    ? requested\n    : \"overview\"\n  const selectTab = useCallback(\n    (next: DiagnosticTabId) => {\n      if (tab === undefined) setOwnTab(next)\n      onTabChange?.(next)\n    },\n    [onTabChange, tab]\n  )\n\n  const rootRef = useRef<HTMLDivElement>(null)\n  const width = usePanelWidth(rootRef)\n  const iconRail = width !== null && width < RAIL_ICON_MAX_WIDTH\n\n  // The \"ago\" readouts are the one thing in the panel that goes stale while\n  // nothing arrives from the host, so the panel keeps its own coarse clock.\n  // It ticks only while mounted, which is only while the panel is open.\n  const [nowMs, setNowMs] = useState(() => Date.now())\n  useEffect(() => {\n    if (typeof window === \"undefined\") return\n    const timer = window.setInterval(() => setNowMs(Date.now()), TIME_AGO_REFRESH_MS)\n    return () => window.clearInterval(timer)\n  }, [])\n\n  const [reportState, setReportState] = useState<\"idle\" | \"copied\" | \"failed\">(\"idle\")\n  /**\n   * \"Copy report\" copies BOTH forms: the ten-line plain-text summary first,\n   * then the full JSON report under a fence.\n   *\n   * The field report says developers paste this into a chat window. A raw JSON\n   * report is two hundred lines there and nobody reads it; a summary with no\n   * evidence behind it cannot be acted on. Putting the readable form first and\n   * the machine form after means the paste is legible at a glance and still\n   * complete — and a reader who wants the numbers scrolls, rather than asking\n   * for a second copy.\n   */\n  const copyReport = useCallback(() => {\n    const report = session.buildLocalReport()\n    const summary = buildPlainTextSummary({\n      connection: snapshot.connection,\n      ...(snapshot.health ? { health: snapshot.health } : {}),\n      ...(snapshot.identity ? { identity: snapshot.identity } : {}),\n      ...(snapshot.host ? { host: snapshot.host } : {}),\n      feedHealth: snapshot.feedHealth,\n      ...(snapshot.counters ? { counters: snapshot.counters } : {}),\n      nowMs,\n      subscribed: snapshot.subscribed,\n      lifecycle: snapshot.lifecycle,\n    })\n    const payload = `${summary}\\n\\n\\`\\`\\`json\\n${JSON.stringify(report, null, 2)}\\n\\`\\`\\`\\n`\n    void writeClipboard(payload).then((ok) => {\n      setReportState(ok ? \"copied\" : \"failed\")\n      if (typeof window !== \"undefined\")\n        window.setTimeout(() => setReportState(\"idle\"), 1800)\n    })\n  }, [nowMs, session, snapshot])\n\n  const identity = snapshot.identity\n  const buildSummary = buildSummaryLine(identity, nowMs)\n  const buildTitle = identity?.build.timestamp\n    ? `${buildTimestampLabel(identity.build.timestampKind)} ${identity.build.timestamp}`\n    : \"This host reported no build timestamp.\"\n\n  // The one-word verdict, repeated in the header so it is on screen from every\n  // tab rather than only from Overview.\n  const health = useMemo(\n    () =>\n      overallHealth({\n        connection: snapshot.connection,\n        ...(snapshot.health ? { health: snapshot.health } : {}),\n        ...(snapshot.identity ? { identity: snapshot.identity } : {}),\n        ...(snapshot.host ? { host: snapshot.host } : {}),\n        feedHealth: snapshot.feedHealth,\n        ...(snapshot.counters ? { counters: snapshot.counters } : {}),\n        nowMs,\n      }),\n    [nowMs, snapshot]\n  )\n\n  // Roving arrow-key navigation over the rail, which is what `role=\"tablist\"`\n  // promises a screen-reader user. Without it the rail is eleven separate tab\n  // stops and Tab never reaches the panel body in a reasonable number of keys.\n  const onRailKeyDown = useCallback(\n    (event: React.KeyboardEvent) => {\n      const forward =\n        event.key === \"ArrowDown\" || event.key === \"ArrowRight\"\n          ? 1\n          : event.key === \"ArrowUp\" || event.key === \"ArrowLeft\"\n            ? -1\n            : 0\n      if (forward === 0 && event.key !== \"Home\" && event.key !== \"End\") return\n      event.preventDefault()\n      const index = visibleTabs.findIndex((entry) => entry.id === active)\n      const next =\n        event.key === \"Home\"\n          ? 0\n          : event.key === \"End\"\n            ? visibleTabs.length - 1\n            : (index + forward + visibleTabs.length) % visibleTabs.length\n      const target = visibleTabs[next]\n      if (!target) return\n      selectTab(target.id)\n      const node =\n        rootRef.current?.querySelector<HTMLElement>(`#diagnostic-tab-${target.id}`) ??\n        null\n      node?.focus()\n    },\n    [active, selectTab, visibleTabs]\n  )\n\n  return (\n    <div\n      ref={rootRef}\n      className={className}\n      data-diagnostic-panel\n      data-diagnostic-health={health.status}\n      style={{\n        display: \"flex\",\n        flexDirection: \"column\",\n        height: \"100%\",\n        minHeight: 0,\n        background: token.surface,\n        color: token.text,\n        font: `12px/1.45 ${token.font}`,\n        ...style,\n      }}\n    >\n      <header\n        style={{\n          display: \"flex\",\n          alignItems: \"center\",\n          gap: 8,\n          padding: \"6px 10px\",\n          borderBottom: `1px solid ${token.border}`,\n          flex: \"0 0 auto\",\n        }}\n      >\n        <strong style={{ fontSize: 12, letterSpacing: \"0.02em\" }}>Diagnostics</strong>\n        <span\n          data-diagnostic-header-health\n          aria-description={health.reason}\n          style={{\n            fontFamily: token.fontMono,\n            fontSize: 11,\n            color: toneColor(health.tone),\n            flex: \"0 0 auto\",\n          }}\n        >\n          {health.status}\n        </span>\n        <span\n          style={{\n            fontFamily: token.fontMono,\n            fontSize: 11,\n            color: token.textMuted,\n            overflow: \"hidden\",\n            textOverflow: \"ellipsis\",\n            whiteSpace: \"nowrap\",\n            minWidth: 0,\n            flex: 1,\n          }}\n        >\n          {identity?.name ?? \"no identity\"} · {snapshot.connection}\n        </span>\n        <span\n          data-diagnostic-build-summary\n          aria-description={buildTitle}\n          style={{\n            fontFamily: token.fontMono,\n            fontSize: 11,\n            color: token.textMuted,\n            whiteSpace: \"nowrap\",\n            flex: \"0 0 auto\",\n          }}\n        >\n          {buildSummary}\n        </span>\n        {reportState !== \"idle\" ? (\n          <span role=\"status\" style={{ fontSize: 11, color: token.textMuted }}>\n            {reportState === \"copied\" ? \"Report copied\" : \"Copy failed\"}\n          </span>\n        ) : null}\n        {headerActions}\n      </header>\n\n      <div style={{ display: \"flex\", flex: \"1 1 auto\", minHeight: 0 }}>\n        <nav\n          aria-label=\"Diagnostic sections\"\n          role=\"tablist\"\n          aria-orientation=\"vertical\"\n          onKeyDown={onRailKeyDown}\n          style={{\n            display: \"flex\",\n            flexDirection: \"column\",\n            gap: 2,\n            padding: 6,\n            borderRight: `1px solid ${token.border}`,\n            overflowY: \"auto\",\n            flex: \"0 0 auto\",\n          }}\n        >\n          {visibleTabs.map((entry) => {\n            const selected = entry.id === active\n            return (\n              <button\n                key={entry.id}\n                type=\"button\"\n                role=\"tab\"\n                id={`diagnostic-tab-${entry.id}`}\n                aria-selected={selected}\n                aria-controls={`diagnostic-panel-${entry.id}`}\n                // Roving tabindex: one stop for the whole rail, arrows move\n                // inside it. This is what makes the rail one Tab press rather\n                // than eleven on the way to the panel body.\n                tabIndex={selected ? 0 : -1}\n                onClick={() => selectTab(entry.id)}\n                aria-description={\n                  entry.feeds.length\n                    ? `${entry.label} — feeds: ${entry.feeds.join(\", \")}`\n                    : entry.label\n                }\n                style={{\n                  ...buttonStyle,\n                  textAlign: iconRail ? \"center\" : \"left\",\n                  border: \"1px solid transparent\",\n                  background: selected ? token.cap : \"transparent\",\n                  color: selected ? token.text : token.textMuted,\n                  fontWeight: selected ? 600 : 400,\n                  whiteSpace: \"nowrap\",\n                  ...(iconRail\n                    ? {\n                        fontFamily: token.fontMono,\n                        padding: \"5px 4px\",\n                        minWidth: 30,\n                      }\n                    : {}),\n                }}\n              >\n                {iconRail ? (\n                  <>\n                    <span aria-hidden>{DIAGNOSTIC_TAB_GLYPHS[entry.id]}</span>\n                    {/* The label stays in the DOM at every width: it is the\n                        accessible name, and the panel's own e2e harness finds\n                        tabs by their text. Only its pixels are given up. */}\n                    <span style={SR_ONLY}>{entry.label}</span>\n                  </>\n                ) : (\n                  entry.label\n                )}\n              </button>\n            )\n          })}\n        </nav>\n\n        <div\n          role=\"tabpanel\"\n          id={`diagnostic-panel-${active}`}\n          aria-labelledby={`diagnostic-tab-${active}`}\n          tabIndex={0}\n          style={{\n            flex: \"1 1 auto\",\n            minWidth: 0,\n            overflow: \"auto\",\n            padding: \"10px 12px\",\n          }}\n        >\n          {active === \"overview\" ? (\n            <OverviewTab\n              snapshot={snapshot}\n              session={session}\n              nowMs={nowMs}\n              onCopyReport={copyReport}\n              onSelectTab={selectTab}\n            />\n          ) : active === \"host\" ? (\n            <HostTab host={snapshot.host} />\n          ) : active === \"latency\" && latencyPlan ? (\n            <LatencyTab plan={latencyPlan} host={snapshot.host} />\n          ) : active === \"transport\" ? (\n            <TransportTab\n              transport={snapshot.transport}\n              clock={snapshot.clock}\n              capabilities={snapshot.capabilities}\n              session={session}\n            />\n          ) : active === \"midi\" ? (\n            <MidiTab midi={snapshot.midi} />\n          ) : active === \"audio\" ? (\n            <AudioTab\n              meters={snapshot.meters}\n              capabilities={snapshot.capabilities}\n              sampleRate={snapshot.host?.sampleRate}\n              session={session}\n              live={live}\n            />\n          ) : active === \"parameters\" ? (\n            <ParametersTab params={snapshot.params} schema={schema} />\n          ) : active === \"presets\" ? (\n            <PresetsTab\n              presets={snapshot.presets}\n              capabilities={snapshot.capabilities}\n              stateBudget={snapshot.identity?.state.maxBytes}\n              state={snapshot.state}\n              session={session}\n            />\n          ) : active === \"sampler\" ? (\n            <SamplerTab\n              banks={snapshot.banks}\n              presets={snapshot.presets}\n              counters={snapshot.counters}\n              lifecycle={snapshot.lifecycle}\n              runtimeStatus={runtimeStatus}\n              capabilities={snapshot.capabilities}\n              session={session}\n            />\n          ) : active === \"events\" ? (\n            <EventsTab lifecycle={snapshot.lifecycle} />\n          ) : active === \"stimulus\" ? (\n            <StimulusTab capabilities={snapshot.capabilities} session={session} />\n          ) : active === \"performance\" ? (\n            <PerformanceTab\n              counters={snapshot.counters}\n              capabilities={snapshot.capabilities}\n              dropped={snapshot.dropped}\n              session={session}\n            />\n          ) : (\n            <PackageTab\n              identity={snapshot.identity}\n              license={snapshot.license}\n              nowMs={nowMs}\n            />\n          )}\n        </div>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "@ui/diagnostic-panel.tsx"
    },
    {
      "path": "components/ui/diagnostic-panel-chrome.tsx",
      "content": "/**\n * Source: https://maru.audio/ui-kit/diagnostic-panel\n * Copyright © [Maru](https://maru.audio)\n *\n * Maru UI Kit — https://maru.audio/ui-kit\n *\n * Installed from the Maru UI registry. This file is yours now: edit it\n * freely, it will not be overwritten unless you re-run the add command.\n *\n * Keep this item’s companion files and CSS imports together. Dependencies\n * declared by the registry are installed with the source.\n */\n/**\n * The panel's shared presentation atoms: the field table, the Unreported cell,\n * badges, section headers and the disabled-with-a-reason control wrapper.\n *\n * They live in one file because they encode a single editorial rule that every\n * tab has to obey identically — a missing value looks like a missing value,\n * everywhere, and never like a zero. Letting each tab spell its own empty state\n * is how \"0 ms latency\" ends up on screen for a host that reports nothing.\n *\n * Colours come from `control-theme`'s `token()` so the panel inherits whatever\n * surface it is dropped into, with no Tailwind dependency — this component ends\n * up inside plugin webviews that have no build step of their own.\n */\n\nimport { useCallback, useLayoutEffect, useRef, useState } from \"react\"\nimport type { CSSProperties, ReactNode } from \"react\"\n\nimport { token } from \"maruaudio/ui/shared/theme\"\nimport {\n  TABLE_WINDOW_THRESHOLD,\n  UNREPORTED_LABEL,\n  isUnreported,\n  tableWindow,\n  type BadgeTone,\n  type DiagnosticBadge,\n  type StatusCell,\n} from \"maruaudio/ui/shared/diagnostic-panel-core\"\n\nconst TONE_COLOR: Readonly<Record<BadgeTone, string>> = {\n  neutral: token.textMuted,\n  good: \"var(--uikit-diagnostic-good, #34d399)\",\n  warn: \"var(--uikit-diagnostic-warn, #fbbf24)\",\n  bad: \"var(--uikit-diagnostic-bad, #fb7185)\",\n  info: token.accent2,\n}\n\n/** The colour a tone paints text in. Exported so tabs can tint their own\n * readouts on the same scale as the badges. */\nexport function toneColor(tone: BadgeTone): string {\n  return TONE_COLOR[tone]\n}\n\nexport function Badge({ badge }: { readonly badge: DiagnosticBadge }) {\n  return (\n    <span\n      aria-description={badge.title}\n      style={{\n        display: \"inline-block\",\n        padding: \"1px 6px\",\n        borderRadius: 4,\n        fontFamily: token.fontMono,\n        fontSize: 11,\n        lineHeight: \"16px\",\n        color: toneColor(badge.tone),\n        background: \"color-mix(in oklab, currentColor 12%, transparent)\",\n        whiteSpace: \"nowrap\",\n      }}\n    >\n      {badge.label}\n    </span>\n  )\n}\n\n/** The one shared \"this host never said\" cell. Every tab renders this rather\n * than an em-dash or a blank, so absence is legible as absence. */\nexport function Unreported({ description }: {\n  readonly description?: string\n}) {\n  return (\n    <span\n      aria-description={description ?? \"Not reported by this host.\"}\n      style={{\n        color: token.textMuted,\n        fontStyle: \"italic\",\n        fontSize: 11,\n        opacity: 0.75,\n      }}\n    >\n      {UNREPORTED_LABEL}\n    </span>\n  )\n}\n\nexport interface FieldProps {\n  readonly label: string\n  /** `undefined`/`null` renders {@link Unreported}; everything else renders. */\n  readonly value?: unknown\n  /** Overrides `value` rendering entirely — for badges and nested markup. */\n  readonly children?: ReactNode\n  readonly description?: string\n  readonly mono?: boolean\n}\n\n/** One label/value row. With neither `children` nor a reported `value` it\n * renders the Unreported cell — the default is honest, so a tab cannot forget. */\nexport function Field({ label, value, children, description, mono = true }: FieldProps) {\n  const showUnreported = children === undefined && isUnreported(value)\n  return (\n    <div\n      aria-description={description}\n      style={{\n        display: \"grid\",\n        gridTemplateColumns: \"minmax(9rem, 40%) minmax(0, 1fr)\",\n        gap: 8,\n        padding: \"3px 0\",\n        borderBottom: `1px solid ${token.border}`,\n        alignItems: \"baseline\",\n      }}\n    >\n      <span style={{ color: token.textMuted, fontSize: 11 }}>{label}</span>\n      <span\n        style={{\n          fontFamily: mono ? token.fontMono : token.font,\n          fontSize: 12,\n          color: token.text,\n          wordBreak: \"break-word\",\n          minWidth: 0,\n        }}\n      >\n        {showUnreported ? <Unreported /> : (children ?? String(value))}\n      </span>\n    </div>\n  )\n}\n\nexport function Section({\n  title,\n  actions,\n  children,\n}: {\n  readonly title: string\n  readonly actions?: ReactNode\n  readonly children: ReactNode\n}) {\n  return (\n    <section style={{ marginBottom: 16 }}>\n      <header\n        style={{\n          display: \"flex\",\n          alignItems: \"center\",\n          justifyContent: \"space-between\",\n          gap: 8,\n          marginBottom: 6,\n        }}\n      >\n        <h3\n          style={{\n            margin: 0,\n            fontSize: 11,\n            fontWeight: 600,\n            letterSpacing: \"0.08em\",\n            textTransform: \"uppercase\",\n            color: token.textMuted,\n          }}\n        >\n          {title}\n        </h3>\n        {actions}\n      </header>\n      {children}\n    </section>\n  )\n}\n\n/** Shown in place of a tab body when the feed behind it was never reported.\n * The tab itself stays reachable: a developer needs to see that the feed\n * exists and that this host does not send it. */\nexport function EmptyFeed({ reason }: { readonly reason: string }) {\n  return (\n    <div\n      style={{\n        padding: \"18px 12px\",\n        borderRadius: token.radius,\n        border: `1px dashed ${token.border}`,\n        color: token.textMuted,\n        fontSize: 12,\n        textAlign: \"center\",\n      }}\n    >\n      {reason}\n    </div>\n  )\n}\n\nexport const buttonStyle: CSSProperties = {\n  appearance: \"none\",\n  border: `1px solid ${token.border}`,\n  borderRadius: 6,\n  background: token.cap,\n  color: token.text,\n  font: `500 11px/1.4 ${token.font}`,\n  padding: \"4px 9px\",\n  cursor: \"pointer\",\n}\n\nexport const inputStyle: CSSProperties = {\n  appearance: \"none\",\n  border: `1px solid ${token.border}`,\n  borderRadius: 6,\n  background: token.surface,\n  color: token.text,\n  font: `12px/1.4 ${token.fontMono}`,\n  padding: \"3px 6px\",\n  minWidth: 0,\n}\n\nexport interface ActionProps {\n  readonly label: string\n  readonly onClick: () => void\n  /** Non-null disables the control and supplies its accessible description. */\n  readonly disabledReason?: string | null\n  readonly description?: string\n}\n\n/** A button that, when its capability is missing, stays visible and says so. */\nexport function Action({ label, onClick, disabledReason, description }: ActionProps) {\n  const disabled = Boolean(disabledReason)\n  return (\n    <button\n      type=\"button\"\n      onClick={onClick}\n      disabled={disabled}\n      aria-description={description ?? disabledReason ?? undefined}\n      style={{\n        ...buttonStyle,\n        cursor: disabled ? \"not-allowed\" : \"pointer\",\n        opacity: disabled ? 0.45 : 1,\n      }}\n    >\n      {label}\n    </button>\n  )\n}\n\n/** A scrollable monospace table. Wide content scrolls inside the drawer\n * instead of forcing the drawer itself wider. */\nexport function Table({\n  head,\n  children,\n  empty,\n  caption,\n}: {\n  readonly head: readonly string[]\n  readonly children: ReactNode\n  readonly empty?: ReactNode\n  /** Screen-reader description of what the table lists. */\n  readonly caption?: string\n}) {\n  const hasRows = Array.isArray(children) ? children.length > 0 : Boolean(children)\n  return (\n    <div style={{ overflowX: \"auto\", maxWidth: \"100%\" }}>\n      <table\n        style={{\n          width: \"100%\",\n          borderCollapse: \"collapse\",\n          fontFamily: token.fontMono,\n          fontSize: 11,\n          color: token.text,\n        }}\n      >\n        {caption ? <caption style={SR_ONLY}>{caption}</caption> : null}\n        <thead>\n          <tr>\n            {head.map((cell) => (\n              <th\n                key={cell}\n                scope=\"col\"\n                style={{\n                  textAlign: \"left\",\n                  padding: \"3px 6px\",\n                  borderBottom: `1px solid ${token.border}`,\n                  color: token.textMuted,\n                  fontWeight: 600,\n                  fontSize: 10,\n                  textTransform: \"uppercase\",\n                  letterSpacing: \"0.06em\",\n                  whiteSpace: \"nowrap\",\n                }}\n              >\n                {cell}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>\n          {hasRows ? (\n            children\n          ) : (\n            <tr>\n              <td\n                colSpan={head.length}\n                style={{ padding: \"14px 6px\", textAlign: \"center\", color: token.textMuted }}\n              >\n                {empty ?? \"Nothing yet.\"}\n              </td>\n            </tr>\n          )}\n        </tbody>\n      </table>\n    </div>\n  )\n}\n\nexport function Cell({\n  children,\n  align = \"left\",\n  muted = false,\n}: {\n  readonly children: ReactNode\n  readonly align?: \"left\" | \"right\"\n  readonly muted?: boolean\n}) {\n  return (\n    <td\n      style={{\n        padding: \"2px 6px\",\n        borderBottom: `1px solid color-mix(in oklab, ${token.border} 45%, transparent)`,\n        textAlign: align,\n        color: muted ? token.textMuted : token.text,\n        whiteSpace: \"nowrap\",\n      }}\n    >\n      {children}\n    </td>\n  )\n}\n\n/** Visually hidden but announced. The panel has no stylesheet of its own, so\n * the clip rectangle is inline rather than a `.sr-only` class. */\nexport const SR_ONLY: CSSProperties = {\n  position: \"absolute\",\n  width: 1,\n  height: 1,\n  padding: 0,\n  margin: -1,\n  overflow: \"hidden\",\n  clip: \"rect(0 0 0 0)\",\n  whiteSpace: \"nowrap\",\n  border: 0,\n}\n\n/**\n * A fixed-width monospace numeric readout.\n *\n * Meters update at 30 Hz, and a column whose width follows its content makes\n * every label beside it jitter for the whole session. `fontVariantNumeric:\n * tabular-nums` fixes the digit widths and `minWidth` in `ch` fixes the\n * column, so the number changes and nothing else moves.\n */\nexport function Numeric({\n  children,\n  width = 9,\n  tone,\n  description,\n}: {\n  readonly children: ReactNode\n  /** Reserved width, in character widths. */\n  readonly width?: number\n  readonly tone?: BadgeTone\n  readonly description?: string\n}) {\n  return (\n    <span\n      aria-description={description}\n      style={{\n        display: \"inline-block\",\n        minWidth: `${width}ch`,\n        textAlign: \"right\",\n        fontFamily: token.fontMono,\n        fontVariantNumeric: \"tabular-nums\",\n        color: tone ? toneColor(tone) : undefined,\n        whiteSpace: \"pre\",\n      }}\n    >\n      {children}\n    </span>\n  )\n}\n\n/**\n * The Overview's status strip: the row of verdicts a developer reads before\n * anything else.\n *\n * Each cell is a label, a value and a tone. It wraps rather than scrolls,\n * because at 360 px the answer to \"is this healthy\" must still be on screen\n * without a horizontal gesture.\n */\nexport function StatusStrip({ cells }: { readonly cells: readonly StatusCell[] }) {\n  return (\n    <div\n      data-diagnostic-status-strip\n      role=\"group\"\n      aria-label=\"Plugin status\"\n      style={{\n        display: \"flex\",\n        flexWrap: \"wrap\",\n        gap: 6,\n        marginBottom: 12,\n      }}\n    >\n      {cells.map((cell) => (\n        <div\n          key={cell.id}\n          aria-description={cell.title}\n          style={{\n            flex: \"1 1 8.5rem\",\n            minWidth: 0,\n            padding: \"5px 8px\",\n            borderRadius: token.radius,\n            border: `1px solid ${token.border}`,\n            background: token.cap,\n            display: \"grid\",\n            gap: 2,\n          }}\n        >\n          <span\n            style={{\n              fontSize: 9,\n              letterSpacing: \"0.09em\",\n              textTransform: \"uppercase\",\n              color: token.textMuted,\n            }}\n          >\n            {cell.label}\n          </span>\n          <span\n            style={{\n              fontFamily: token.fontMono,\n              fontVariantNumeric: \"tabular-nums\",\n              fontSize: 12,\n              color: toneColor(cell.tone),\n              overflow: \"hidden\",\n              textOverflow: \"ellipsis\",\n              whiteSpace: \"nowrap\",\n            }}\n          >\n            {cell.value}\n          </span>\n        </div>\n      ))}\n    </div>\n  )\n}\n\n/** A toggle chip for a filter. `aria-pressed` rather than a checkbox, because\n * these are toggle buttons and a screen reader should say so. */\nexport function FilterChip({\n  label,\n  active,\n  onToggle,\n  tone,\n  description,\n}: {\n  readonly label: string\n  readonly active: boolean\n  readonly onToggle: () => void\n  readonly tone?: BadgeTone\n  readonly description?: string\n}) {\n  const accent = tone ? toneColor(tone) : token.accent\n  return (\n    <button\n      type=\"button\"\n      aria-pressed={active}\n      onClick={onToggle}\n      aria-description={description}\n      style={{\n        ...buttonStyle,\n        fontSize: 10,\n        padding: \"2px 7px\",\n        fontFamily: token.fontMono,\n        background: active ? accent : token.cap,\n        color: active ? \"#0b0d12\" : token.text,\n        borderColor: active ? accent : token.border,\n      }}\n    >\n      {label}\n    </button>\n  )\n}\n\n/** Height one windowed row is assumed to occupy, in CSS pixels. The table's\n * own cell padding and 11 px monospace line box come to this; it is a constant\n * rather than a measurement because a windowed table must not read back layout\n * every frame. */\nexport const WINDOW_ROW_HEIGHT = 18\n\nexport interface WindowedTableProps<Row> {\n  readonly head: readonly string[]\n  readonly rows: readonly Row[]\n  readonly rowKey: (row: Row, index: number) => string | number\n  readonly renderRow: (row: Row, index: number) => ReactNode\n  readonly empty?: ReactNode\n  readonly caption?: string\n  /** Visible height of the scroll container. */\n  readonly height?: number\n  /** Fixed CSS height of each rendered row when this table is windowed. */\n  readonly rowHeight?: number\n}\n\n/**\n * A table that only renders the rows you can see.\n *\n * The MIDI log holds 512 events per direction and the lifecycle log 256; a\n * panel that renders all of them into the DOM at 30 Hz spends its whole frame\n * budget on rows nobody is looking at. Above\n * {@link TABLE_WINDOW_THRESHOLD} rows this renders the visible band plus an\n * overscan and pads the rest with two spacer rows, so the scrollbar keeps\n * telling the truth about how much log there is.\n *\n * Below the threshold it degrades to a plain table with no scroll container\n * and no listener, because most hosts and most sessions never reach it and\n * windowing a 30-row table is pure overhead.\n */\nexport function WindowedTable<Row>({\n  head,\n  rows,\n  rowKey,\n  renderRow,\n  empty,\n  caption,\n  height = 240,\n  rowHeight = WINDOW_ROW_HEIGHT,\n}: WindowedTableProps<Row>) {\n  const [scrollTop, setScrollTop] = useState(0)\n  const containerRef = useRef<HTMLDivElement | null>(null)\n  const windowed = rows.length > TABLE_WINDOW_THRESHOLD\n\n  const onScroll = useCallback(() => {\n    const node = containerRef.current\n    if (node) setScrollTop(node.scrollTop)\n  }, [])\n\n  // A filter that shrinks the list can leave the container scrolled past its\n  // new end, which would window an empty band and render nothing at all.\n  useLayoutEffect(() => {\n    const node = containerRef.current\n    if (!node) return\n    if (node.scrollTop !== scrollTop) setScrollTop(node.scrollTop)\n  }, [rows.length, scrollTop])\n\n  if (!windowed)\n    return (\n      <Table head={head} empty={empty} caption={caption}>\n        {rows.map((row, index) => (\n          <ScopedRow key={rowKey(row, index)}>{renderRow(row, index)}</ScopedRow>\n        ))}\n      </Table>\n    )\n\n  const view = tableWindow(rows.length, scrollTop, height, rowHeight)\n  const visible = rows.slice(view.start, view.end)\n\n  return (\n    <div\n      ref={containerRef}\n      onScroll={onScroll}\n      data-diagnostic-windowed\n      style={{ maxHeight: height, overflow: \"auto\", maxWidth: \"100%\" }}\n    >\n      <table\n        style={{\n          width: \"100%\",\n          borderCollapse: \"collapse\",\n          fontFamily: token.fontMono,\n          fontSize: 11,\n          color: token.text,\n        }}\n      >\n        {caption ? (\n          <caption style={SR_ONLY}>\n            {caption} — showing rows {view.start + 1} to {view.end} of {rows.length}.\n          </caption>\n        ) : null}\n        <thead style={{ position: \"sticky\", top: 0, background: token.surface, zIndex: 1 }}>\n          <tr>\n            {head.map((cell) => (\n              <th\n                key={cell}\n                scope=\"col\"\n                style={{\n                  textAlign: \"left\",\n                  padding: \"3px 6px\",\n                  borderBottom: `1px solid ${token.border}`,\n                  color: token.textMuted,\n                  fontWeight: 600,\n                  fontSize: 10,\n                  textTransform: \"uppercase\",\n                  letterSpacing: \"0.06em\",\n                  whiteSpace: \"nowrap\",\n                }}\n              >\n                {cell}\n              </th>\n            ))}\n          </tr>\n        </thead>\n        <tbody>\n          {view.padTop > 0 ? (\n            <tr aria-hidden style={{ height: view.padTop }} />\n          ) : null}\n          {visible.map((row, index) => (\n            <ScopedRow key={rowKey(row, view.start + index)}>\n              {renderRow(row, view.start + index)}\n            </ScopedRow>\n          ))}\n          {view.padBottom > 0 ? (\n            <tr aria-hidden style={{ height: view.padBottom }} />\n          ) : null}\n        </tbody>\n      </table>\n    </div>\n  )\n}\n\n/** `renderRow` returns the row's cells; this wraps them in the `<tr>` so a\n * caller never has to remember the key. */\nfunction ScopedRow({ children }: { readonly children: ReactNode }) {\n  return <tr>{children}</tr>\n}\n",
      "type": "registry:component",
      "target": "@ui/diagnostic-panel-chrome.tsx"
    },
    {
      "path": "components/ui/diagnostic-tabs-info.tsx",
      "content": "/**\n * Source: https://maru.audio/ui-kit/diagnostic-panel\n * Copyright © [Maru](https://maru.audio)\n *\n * Maru UI Kit — https://maru.audio/ui-kit\n *\n * Installed from the Maru UI registry. This file is yours now: edit it\n * freely, it will not be overwritten unless you re-run the add command.\n *\n * Keep this item’s companion files and CSS imports together. Dependencies\n * declared by the registry are installed with the source.\n */\n/**\n * The read-only informational tabs: Overview, Host, Package, Presets,\n * Parameters, Performance.\n *\n * Every value in here comes from the snapshot or renders as Unreported. There\n * are no defaults, no `?? 0` and no `|| \"unknown\"` — a panel that fills a gap\n * with a plausible number is worse than no panel, because a developer will act\n * on it.\n *\n * Each tab takes **only the slice of the snapshot it reads**, not the whole\n * snapshot, and is wrapped in `memo`. That is what makes the panel's cost\n * proportional to what actually changed: a meters frame at 30 Hz changes\n * `snapshot.meters` and leaves `snapshot.params` referentially identical, so\n * the Parameters tab's memo holds and its table is not rebuilt thirty times a\n * second for nothing.\n */\n\nimport { memo, useMemo } from \"react\"\nimport { defaultAudioModuleFaceValue, taperFromPosition } from \"maruaudio/ui/shared/maru/contracts\"\nimport type {\n  AudioModuleLatencyPlan,\n  DiagnosticBankInfo,\n  DiagnosticCapabilities,\n  DiagnosticCounters,\n  DiagnosticFeed,\n  DiagnosticHostInfo,\n  DiagnosticIdentity,\n  DiagnosticLicense,\n  DiagnosticLifecycleEvent,\n  ParamDescriptor,\n  ParamSchema,\n} from \"maruaudio/ui/shared/maru/contracts\"\nimport type {\n  DiagnosticParamEntry,\n  DiagnosticPresetSnapshot,\n  DiagnosticSession,\n  DiagnosticSnapshot,\n} from \"maruaudio/ui/shared/maru/diagnostic-session\"\n\nimport { token } from \"maruaudio/ui/shared/theme\"\nimport {\n  Action,\n  Badge,\n  Cell,\n  EmptyFeed,\n  Field,\n  Numeric,\n  Section,\n  StatusStrip,\n  Table,\n  Unreported,\n  WindowedTable,\n  toneColor,\n} from \"@/components/ui/diagnostic-panel-chrome\"\nimport {\n  bankEventRows,\n  bankLoadProgress,\n  buildModeBadge,\n  buildSummaryLine,\n  buildTimestampLabel,\n  commandUnavailableReason,\n  formatBankHash,\n  formatRelativeEventTime,\n  counterRows,\n  feedHealthRows,\n  formatBytes,\n  formatHz,\n  formatMaybe,\n  formatNumber,\n  formatSamples,\n  formatTimeAgo,\n  overviewStatusCells,\n  UNREPORTED_LABEL,\n  type DiagnosticTabId,\n} from \"maruaudio/ui/shared/diagnostic-panel-core\"\n\n/** The shared clock a tab uses for its \"ago\" readouts, so every one on screen\n * agrees and refreshes together (see `TIME_AGO_REFRESH_MS`). */\nexport interface ClockProps {\n  readonly nowMs?: number\n}\n\nfunction commands(\n  capabilities: DiagnosticCapabilities | undefined\n): readonly string[] | undefined {\n  return capabilities?.commands\n}\n\n// --- Overview ----------------------------------------------------------------\n\nexport interface OverviewTabProps extends ClockProps {\n  readonly snapshot: DiagnosticSnapshot\n  readonly session: DiagnosticSession\n  readonly onCopyReport: () => void\n  /** Lets the strip's problems link to the tab that explains them. */\n  readonly onSelectTab?: (tab: DiagnosticTabId) => void\n}\n\n/**\n * The tab that answers \"is this thing alive and what is it\" — in one screen,\n * without scrolling, at 360 px.\n *\n * The order is the order the questions get asked. The **status strip** first,\n * because the whole point is that a developer should not have to read four\n * tabs to learn that the host stopped draining its feeds. Then the **first\n * error**, which is the single most useful fact when something is wrong. Then\n * the **report button**, which the field report calls the most useful artefact\n * the panel has. Identity and the feed-health table follow, as the evidence\n * behind the strip rather than as the headline.\n */\nfunction OverviewTabImpl({\n  snapshot,\n  session,\n  nowMs,\n  onCopyReport,\n  onSelectTab,\n}: OverviewTabProps) {\n  const health = snapshot.health\n  const identity = snapshot.identity\n  const dropped = snapshot.dropped\n  const anyDropped = dropped.feeds + dropped.midi + dropped.lifecycle > 0\n  const feedHealth = feedHealthRows(snapshot.feedHealth)\n  const at = nowMs ?? Date.now()\n  const cells = overviewStatusCells({\n    connection: snapshot.connection,\n    ...(health ? { health } : {}),\n    ...(identity ? { identity } : {}),\n    ...(snapshot.host ? { host: snapshot.host } : {}),\n    feedHealth: snapshot.feedHealth,\n    ...(snapshot.counters ? { counters: snapshot.counters } : {}),\n    nowMs: at,\n  })\n\n  return (\n    <>\n      <StatusStrip cells={cells} />\n\n      {/* The first error gets its own block above everything else when there\n          is one: a developer who opens the panel because something is broken\n          must not have to find it in a table. */}\n      {health?.firstError ? (\n        <div\n          role=\"alert\"\n          style={{\n            marginBottom: 12,\n            padding: \"8px 10px\",\n            borderRadius: token.radius,\n            border: `1px solid ${toneColor(\"bad\")}`,\n            background: \"color-mix(in oklab, currentColor 8%, transparent)\",\n            color: toneColor(\"bad\"),\n            fontFamily: token.fontMono,\n            fontSize: 11,\n            wordBreak: \"break-word\",\n          }}\n        >\n          <strong>{health.firstError.code}</strong>: {health.firstError.message}\n        </div>\n      ) : null}\n\n      <Section\n        title=\"Report\"\n        actions={\n          <Action\n            label=\"Reset counters\"\n            onClick={() => session.stimulate({ kind: \"resetCounters\" })}\n            disabledReason={commandUnavailableReason(\n              \"resetCounters\",\n              commands(snapshot.capabilities)\n            )}\n          />\n        }\n      >\n        <div style={{ display: \"flex\", gap: 8, alignItems: \"center\", flexWrap: \"wrap\" }}>\n          <Action\n            label=\"Copy report\"\n            onClick={onCopyReport}\n            description=\"Copies a ten-line plain-text summary for chat, followed by the full JSON report.\"\n          />\n          <span style={{ color: token.textMuted, fontSize: 11 }}>\n            A ten-line summary for chat, then the full JSON report beneath it.\n          </span>\n        </div>\n      </Section>\n\n      <Section title=\"Runtime\">\n        <Field label=\"Runtime health\">\n          {health ? (\n            <span\n              style={{\n                color:\n                  health.status === \"healthy\"\n                    ? toneColor(\"good\")\n                    : health.status === \"degraded\"\n                      ? toneColor(\"warn\")\n                      : toneColor(\"bad\"),\n                fontFamily: token.fontMono,\n              }}\n            >\n              {health.status}\n            </span>\n          ) : undefined}\n        </Field>\n        <Field\n          label=\"First error\"\n          value={health?.firstError ? undefined : null}\n          description=\"The first runtime diagnostic recorded since activation.\"\n        >\n          {health?.firstError ? (\n            <span style={{ color: toneColor(\"bad\") }}>\n              {health.firstError.code}: {health.firstError.message}\n            </span>\n          ) : health ? (\n            <span style={{ color: token.textMuted }}>none</span>\n          ) : undefined}\n        </Field>\n        <Field label=\"Build mode\">\n          <Badge badge={buildModeBadge(identity?.build.mode)} />\n        </Field>\n        <Field label=\"Connection\">\n          <span style={{ fontFamily: token.fontMono }}>{snapshot.connection}</span>\n        </Field>\n      </Section>\n\n      <Section\n        title=\"Feed health\"\n        actions={\n          onSelectTab ? (\n            <Action label=\"Performance →\" onClick={() => onSelectTab(\"performance\")} />\n          ) : undefined\n        }\n      >\n        <Table\n          head={[\"Feed\", \"Expected\", \"Observed\", \"Age\", \"Dropped\", \"Verdict\"]}\n          empty=\"Not measured — open() has not subscribed yet.\"\n          caption=\"Per-feed delivery health, measured from arrival timestamps.\"\n        >\n          {feedHealth.map((row) => (\n            <tr key={row.key} aria-description={row.title}>\n              <Cell muted>{row.feed}</Cell>\n              <Cell align=\"right\">\n                <Numeric width={7}>{row.expected}</Numeric>\n              </Cell>\n              <Cell align=\"right\">\n                <Numeric width={7} tone={row.tone}>\n                  {row.observed}\n                </Numeric>\n              </Cell>\n              <Cell align=\"right\">\n                <Numeric width={8}>{row.age}</Numeric>\n              </Cell>\n              <Cell align=\"right\">\n                <Numeric width={6}>{row.dropped}</Numeric>\n              </Cell>\n              <Cell>\n                <Badge badge={{ label: row.verdict, tone: row.tone, title: row.title }} />\n              </Cell>\n            </tr>\n          ))}\n        </Table>\n      </Section>\n\n      <Section title=\"Identity\">\n        <Field\n          label=\"Build\"\n          description={\n            identity?.build.timestamp\n              ? `${buildTimestampLabel(identity.build.timestampKind)} ${identity.build.timestamp}`\n              : \"This host reported no build timestamp.\"\n          }\n        >\n          <span style={{ fontFamily: token.fontMono }}>\n            {buildSummaryLine(identity, at)}\n          </span>\n        </Field>\n        <Field label=\"Module\" value={identity?.name} />\n        <Field label=\"Id\" value={identity?.moduleId} />\n        <Field label=\"Vendor\" value={identity?.vendor} />\n        <Field label=\"Version\" value={identity?.version} />\n        <Field label=\"Class\" value={identity?.hostClass} />\n        <Field label=\"Target\" value={identity?.target} />\n        <Field label=\"SDK\" value={identity?.sdkVersion} />\n      </Section>\n\n      <Section title=\"Feeds\">\n        <Field\n          label=\"Subscribed\"\n          description=\"What open() last asked this host for.\"\n          value={snapshot.subscribed.length ? undefined : null}\n        >\n          {snapshot.subscribed.length ? (\n            <span style={{ fontFamily: token.fontMono }}>\n              {snapshot.subscribed.join(\", \")}\n            </span>\n          ) : undefined}\n        </Field>\n        <Field\n          label=\"Declared\"\n          value={snapshot.capabilities ? undefined : null}\n          description=\"Feeds the host says it can produce.\"\n        >\n          {snapshot.capabilities ? (\n            <span style={{ fontFamily: token.fontMono }}>\n              {snapshot.capabilities.feeds.length\n                ? snapshot.capabilities.feeds.join(\", \")\n                : \"none\"}\n            </span>\n          ) : undefined}\n        </Field>\n        <Field label=\"Max feed rate\" value={snapshot.capabilities?.maxFeedHz}>\n          {snapshot.capabilities ? formatHz(snapshot.capabilities.maxFeedHz) : undefined}\n        </Field>\n        <Field\n          label=\"Dropped\"\n          description=\"Frames and events neither this session nor the host could keep.\"\n        >\n          <span\n            style={{\n              fontFamily: token.fontMono,\n              color: anyDropped ? toneColor(\"warn\") : token.text,\n            }}\n          >\n            {dropped.feeds} feed / {dropped.midi} midi / {dropped.lifecycle} lifecycle\n          </span>\n        </Field>\n      </Section>\n    </>\n  )\n}\n\nexport const OverviewTab = memo(OverviewTabImpl)\n\n// --- Host --------------------------------------------------------------------\n\nfunction HostTabImpl({ host }: { readonly host: DiagnosticHostInfo | undefined }) {\n  if (!host)\n    return (\n      <EmptyFeed reason=\"This host reported no host block. Sample rate, block size, buses and latency are unknown — not zero.\" />\n    )\n  const rateMismatch =\n    host.internalSampleRate !== undefined && host.internalSampleRate !== host.sampleRate\n  return (\n    <>\n      <Section title=\"Host application\">\n        <Field label=\"Name\" value={host.hostName} />\n        <Field label=\"Version\" value={host.hostVersion} />\n        <Field label=\"Path\" value={host.hostPath} />\n        <Field label=\"Validator\" value={host.validatorHost} />\n      </Section>\n\n      <Section title=\"Audio configuration\">\n        <Field label=\"Sample rate\">{formatHz(host.sampleRate)}</Field>\n        <Field\n          label=\"Internal rate\"\n          value={host.internalSampleRate}\n          description={\n            rateMismatch\n              ? \"The kernel runs at a different rate from the host — the sample-rate adapter is engaged, and its latency is included below.\"\n              : undefined\n          }\n        >\n          {host.internalSampleRate === undefined ? undefined : (\n            <span style={{ color: rateMismatch ? toneColor(\"info\") : undefined }}>\n              {formatHz(host.internalSampleRate)}\n              {rateMismatch ? \" (adapted)\" : \"\"}\n            </span>\n          )}\n        </Field>\n        <Field label=\"Max block\">{formatNumber(host.maxBlockFrames)} frames</Field>\n        <Field label=\"Last block\" value={host.lastBlockFrames}>\n          {host.lastBlockFrames === undefined\n            ? undefined\n            : `${formatNumber(host.lastBlockFrames)} frames`}\n        </Field>\n        <Field label=\"Process mode\" value={host.processMode} />\n        <Field label=\"Sample size\" value={host.sampleSize}>\n          {`${host.sampleSize}-bit float`}\n        </Field>\n        <Field label=\"Latency\">{formatSamples(host.latencySamples, host.sampleRate)}</Field>\n        <Field label=\"Tail\">{formatSamples(host.tailSamples, host.sampleRate)}</Field>\n        <Field label=\"Bypassed\" value={host.bypassed} />\n      </Section>\n\n      <Section title=\"Buses\">\n        <Table\n          head={[\"Bus\", \"Dir\", \"Ch\", \"Layout\", \"Active\"]}\n          empty=\"No buses reported.\"\n          caption=\"Audio buses this host configured.\"\n        >\n          {host.buses.map((bus) => (\n            <tr key={`${bus.direction}:${bus.id}`}>\n              <Cell>{bus.id}</Cell>\n              <Cell muted>{bus.direction}</Cell>\n              <Cell align=\"right\">\n                <Numeric width={3}>{bus.channels}</Numeric>\n              </Cell>\n              <Cell muted>{bus.layout ?? <Unreported />}</Cell>\n              <Cell>{bus.active ? \"yes\" : \"no\"}</Cell>\n            </tr>\n          ))}\n        </Table>\n      </Section>\n    </>\n  )\n}\n\nexport const HostTab = memo(HostTabImpl)\n\n// --- Latency -----------------------------------------------------------------\n\nfunction LatencyTabImpl({\n  plan,\n  host,\n}: {\n  readonly plan: AudioModuleLatencyPlan\n  readonly host: DiagnosticHostInfo | undefined\n}) {\n  const nodeById = new Map(plan.nodes.map((node) => [node.id, node]))\n  const maxFrames = Math.max(1, plan.totalFrames)\n  const adapted =\n    host?.internalSampleRate !== undefined &&\n    host.internalSampleRate !== host.sampleRate\n  const directlyComparable =\n    host !== undefined && host.sampleRate === plan.sampleRate && !adapted\n  const matched = directlyComparable\n    ? host.latencySamples === plan.totalFrames\n    : undefined\n  const verdict =\n    host === undefined\n      ? \"runtime unreported\"\n      : adapted\n        ? \"host total includes rate adapter\"\n        : !directlyComparable\n          ? \"different host rate\"\n          : matched\n            ? \"plan = runtime\"\n            : \"plan/runtime mismatch\"\n  const verdictTone =\n    matched === true\n      ? toneColor(\"good\")\n      : matched === false\n        ? toneColor(\"bad\")\n        : toneColor(\"info\")\n\n  return (\n    <>\n      <Section title=\"Latency contract\">\n        <Field label=\"Graph plan\">\n          {formatSamples(plan.totalFrames, plan.sampleRate)}\n        </Field>\n        <Field label=\"Runtime report\" value={host?.latencySamples}>\n          {host ? formatSamples(host.latencySamples, host.sampleRate) : undefined}\n        </Field>\n        <Field label=\"Comparison\">\n          <span\n            data-latency-verdict={\n              matched === undefined ? \"not-comparable\" : matched ? \"matched\" : \"mismatch\"\n            }\n            style={{ color: verdictTone, fontFamily: token.fontMono }}\n          >\n            {verdict}\n          </span>\n        </Field>\n      </Section>\n\n      <Section title=\"Compensation timeline\">\n        <div\n          data-latency-debugger\n          style={{ display: \"grid\", gap: 7, minWidth: 300 }}\n        >\n          <div\n            aria-hidden=\"true\"\n            style={{\n              display: \"grid\",\n              gridTemplateColumns: \"minmax(110px, 1fr) minmax(180px, 3fr) 70px\",\n              gap: 8,\n              color: token.textMuted,\n              fontFamily: token.fontMono,\n              fontSize: 10,\n            }}\n          >\n            <span>route</span>\n            <span style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n              <span>0</span>\n              <span>{plan.totalFrames} frames</span>\n            </span>\n            <span style={{ textAlign: \"right\" }}>inserted</span>\n          </div>\n          {plan.edges.map((edge, index) => {\n            const sourceArrival =\n              edge.from === \"input\" ? 0 : nodeById.get(edge.from)?.arrivalFrames ?? 0\n            const start = (sourceArrival / maxFrames) * 100\n            const width = (edge.compensationFrames / maxFrames) * 100\n            return (\n              <div\n                key={`${edge.from}:${edge.to}:${index}`}\n                style={{\n                  display: \"grid\",\n                  gridTemplateColumns: \"minmax(110px, 1fr) minmax(180px, 3fr) 70px\",\n                  alignItems: \"center\",\n                  gap: 8,\n                }}\n              >\n                <span\n                  aria-description={`${edge.from} to ${edge.to}`}\n                  style={{\n                    overflow: \"hidden\",\n                    textOverflow: \"ellipsis\",\n                    whiteSpace: \"nowrap\",\n                    fontFamily: token.fontMono,\n                    fontSize: 10,\n                  }}\n                >\n                  {edge.from} → {edge.to}\n                </span>\n                <div\n                  style={{\n                    position: \"relative\",\n                    height: 12,\n                    borderTop: `1px solid ${token.border}`,\n                  }}\n                >\n                  <span\n                    aria-hidden=\"true\"\n                    style={{\n                      position: \"absolute\",\n                      left: `calc(${start}% - 2px)`,\n                      top: -3,\n                      width: 4,\n                      height: 6,\n                      borderRadius: 2,\n                      background: token.textMuted,\n                    }}\n                  />\n                  {edge.compensationFrames > 0 ? (\n                    <span\n                      data-latency-compensation-frames={edge.compensationFrames}\n                      style={{\n                        position: \"absolute\",\n                        left: `${start}%`,\n                        width: `${width}%`,\n                        top: 2,\n                        height: 7,\n                        minWidth: 2,\n                        background: toneColor(\"info\"),\n                      }}\n                    />\n                  ) : null}\n                </div>\n                <Numeric width={6}>\n                  {edge.compensationFrames > 0\n                    ? `+${edge.compensationFrames}`\n                    : \"0\"}\n                </Numeric>\n              </div>\n            )\n          })}\n        </div>\n      </Section>\n\n      <Section title=\"Node arrivals\">\n        <Table\n          head={[\"Node\", \"Type\", \"Own\", \"Arrival\"]}\n          empty=\"No graph nodes reported.\"\n          caption=\"Intrinsic node latency and longest-path output arrival at the plan rate.\"\n        >\n          {plan.nodes.map((node) => (\n            <tr key={node.id}>\n              <Cell>{node.id}</Cell>\n              <Cell muted>{node.type}</Cell>\n              <Cell align=\"right\">\n                <Numeric width={5}>{node.intrinsicFrames}</Numeric>\n              </Cell>\n              <Cell align=\"right\">\n                <Numeric width={5}>{node.arrivalFrames}</Numeric>\n              </Cell>\n            </tr>\n          ))}\n        </Table>\n      </Section>\n    </>\n  )\n}\n\nexport const LatencyTab = memo(LatencyTabImpl)\n\n// --- Package -----------------------------------------------------------------\n\nexport interface PackageTabProps extends ClockProps {\n  readonly identity: DiagnosticIdentity | undefined\n  readonly license: DiagnosticLicense | undefined\n}\n\nfunction PackageTabImpl({ identity, license, nowMs }: PackageTabProps) {\n  const at = nowMs ?? Date.now()\n  const ui = identity?.ui\n  // `uiSha256` is the digest the NATIVE build was configured with; `ui.sha256`\n  // is what the served bundle's own manifest claims. They are shown as two\n  // rows on purpose — a disagreement between them is the finding.\n  const uiSha = ui?.sha256 ?? identity?.uiSha256\n  const buildTimestampRow = buildTimestampLabel(identity?.build.timestampKind)\n  return (\n    <>\n      <Section title=\"Artifact\">\n        <Field label=\"Module id\" value={identity?.moduleId} />\n        <Field label=\"Class\" value={identity?.hostClass} />\n        <Field label=\"Target\" value={identity?.target} />\n        <Field label=\"Version\" value={identity?.version} />\n        <Field label=\"SDK version\" value={identity?.sdkVersion} />\n        <Field label=\"Build mode\">\n          <Badge badge={buildModeBadge(identity?.build.mode)} />\n        </Field>\n        <Field label=\"Build config\" value={identity?.build.configuration} />\n        <Field\n          label={buildTimestampRow}\n          value={identity?.build.timestamp}\n          description={\n            identity?.build.timestamp\n              ? undefined\n              : \"A reproducible release build records no wall clock.\"\n          }\n        >\n          {identity?.build.timestamp ? (\n            <span style={{ fontFamily: token.fontMono }}>\n              {identity.build.timestamp}{\" \"}\n              <span style={{ color: token.textMuted }}>\n                ({formatTimeAgo(identity.build.timestamp, at)})\n              </span>\n            </span>\n          ) : undefined}\n        </Field>\n        <Field label=\"Source revision\" value={identity?.sourceRevision} />\n        <Field label=\"Artifact sha256\" value={identity?.artifactSha256} />\n        <Field label=\"Processor CID\" value={identity?.processorCid} />\n        <Field label=\"Controller CID\" value={identity?.controllerCid} />\n      </Section>\n\n      <Section title=\"UI bundle\">\n        <Field\n          label=\"UI built\"\n          value={ui?.buildTime}\n          description=\"From the served ui/manifest.json, not from the native build.\"\n        >\n          {ui?.buildTime ? (\n            <span style={{ fontFamily: token.fontMono }}>\n              {ui.buildTime}{\" \"}\n              <span style={{ color: token.textMuted }}>\n                ({formatTimeAgo(ui.buildTime, at)})\n              </span>\n            </span>\n          ) : undefined}\n        </Field>\n        <Field label=\"UI revision\" value={ui?.sourceRevision} />\n        <Field\n          label=\"UI sha256\"\n          value={uiSha}\n          description={\n            ui?.sha256 !== undefined &&\n            identity?.uiSha256 !== undefined &&\n            ui.sha256 !== identity.uiSha256\n              ? `The served bundle reports ${ui.sha256}; the native build was configured with ${identity.uiSha256}.`\n              : undefined\n          }\n        />\n      </Section>\n\n      <Section title=\"Processing\">\n        <Field label=\"Rate policy\" value={identity?.ratePolicy?.mode} />\n        <Field label=\"State version\" value={identity?.state.version} />\n        <Field label=\"State budget\" value={identity?.state.maxBytes}>\n          {identity ? formatBytes(identity.state.maxBytes) : undefined}\n        </Field>\n      </Section>\n\n      <Section title=\"Ports\">\n        <Table\n          head={[\"Port\", \"Kind\", \"Dir\", \"Role\", \"Ch\"]}\n          empty=\"No ports reported.\"\n          caption=\"Ports this module declares.\"\n        >\n          {(identity?.ports ?? []).map((port) => (\n            <tr key={`${port.direction}:${port.kind}:${port.id}`}>\n              <Cell>{port.id}</Cell>\n              <Cell muted>{port.kind}</Cell>\n              <Cell muted>{port.direction}</Cell>\n              <Cell muted>{port.busRole}</Cell>\n              <Cell align=\"right\">\n                <Numeric width={3}>{port.channels ?? <Unreported />}</Numeric>\n              </Cell>\n            </tr>\n          ))}\n        </Table>\n      </Section>\n\n      <Section title=\"License\">\n        <Field label=\"Status\" value={license?.status} />\n        <Field label=\"Provider\" value={license?.provider} />\n        <Field label=\"Product\" value={license?.productId} />\n        <Field label=\"Revision\" value={license?.revision} />\n        <Field label=\"Checked at\" value={license?.checkedAt} />\n        <Field label=\"Expires\" value={license?.expiresAt} />\n        <Field label=\"Permits paid features\" value={license?.permitsPaidFeatures} />\n      </Section>\n    </>\n  )\n}\n\nexport const PackageTab = memo(PackageTabImpl)\n\n// --- Parameters --------------------------------------------------------------\n\nfunction formatParameterRange(param: ParamDescriptor): string {\n  if (param.type === \"bool\") return \"0–1\"\n  if (param.type === \"enum\") return `0–${Math.max(0, (param.options?.length ?? 0) - 1)}`\n  return `${param.min ?? 0}–${param.max ?? 1}`\n}\n\n/** Draw the descriptor's real position-to-value response, scaled to this glyph. */\nfunction parameterTaperPath(param: ParamDescriptor): string {\n  const min = param.min ?? 0\n  const max = param.max ?? 1\n  const span = max - min\n  return Array.from({ length: 13 }, (_, index) => {\n    const position = index / 12\n    const value = taperFromPosition(param.taper, position, min, max)\n    const fraction =\n      span === 0 ? position : Math.min(1, Math.max(0, (value - min) / span))\n    const x = (2 + position * 28).toFixed(1)\n    const y = (11 - fraction * 9).toFixed(1)\n    return `${index === 0 ? \"M\" : \"L\"}${x} ${y}`\n  }).join(\" \")\n}\n\nfunction ParameterTaper({ descriptor }: { readonly descriptor?: ParamDescriptor }) {\n  const taper = descriptor?.type === \"float\" ? descriptor.taper ?? \"linear\" : undefined\n  return (\n    <span\n      style={{\n        display: \"flex\",\n        flexDirection: \"column\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        height: 23,\n        lineHeight: \"11px\",\n        width: \"max-content\",\n      }}\n    >\n      {taper && descriptor ? (\n        <svg\n          aria-hidden=\"true\"\n          data-taper-curve={taper}\n          width=\"32\"\n          height=\"11\"\n          viewBox=\"0 0 32 13\"\n          fill=\"none\"\n        >\n          <path\n            d={parameterTaperPath(descriptor)}\n            stroke=\"currentColor\"\n            strokeWidth=\"1.5\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n          />\n        </svg>\n      ) : null}\n      <span>{descriptor ? taper ?? \"—\" : <Unreported />}</span>\n    </span>\n  )\n}\n\ninterface ParameterDiagnosticRow {\n  readonly path: string\n  readonly descriptor?: ParamDescriptor\n  readonly live?: DiagnosticParamEntry\n}\n\nfunction ParametersTabImpl({\n  params,\n  schema,\n}: {\n  readonly params: readonly DiagnosticParamEntry[]\n  readonly schema?: ParamSchema\n}) {\n  const rows = useMemo<readonly ParameterDiagnosticRow[]>(() => {\n    const liveByPath = new Map(params.map((param) => [param.path, param]))\n    const authored = (schema?.params ?? []).map((descriptor) => ({\n      path: descriptor.path,\n      descriptor,\n      live: liveByPath.get(descriptor.path),\n    }))\n    const declared = new Set(authored.map((row) => row.path))\n    return [\n      ...authored,\n      ...params.filter((param) => !declared.has(param.path)).map((live) => ({\n        path: live.path,\n        live,\n      })),\n    ]\n  }, [params, schema])\n\n  return (\n    <Section title={`Parameters (${rows.length})`}>\n      <WindowedTable\n        head={[\"Path\", \"Value\", \"Norm\", \"Range\", \"Default\", \"Taper\", \"Source\", \"Edit\"]}\n        rows={rows}\n        rowKey={(row) => row.path}\n        empty=\"No parameters declared or reported.\"\n        caption=\"Live values and write sources come from the host. Range, default and taper come from the module's parameter schema.\"\n        height={320}\n        rowHeight={28}\n        renderRow={({ path, live, descriptor }) => (\n          <>\n            <Cell>{path}</Cell>\n            <Cell align=\"right\">\n              <Numeric width={8}>\n                {live ? formatNumber(live.value) : <Unreported />}\n              </Numeric>\n            </Cell>\n            <Cell align=\"right\" muted>\n              <Numeric width={7}>\n                {live?.normalized === undefined ? (\n                  <Unreported />\n                ) : (\n                  formatNumber(live.normalized)\n                )}\n              </Numeric>\n            </Cell>\n            <Cell align=\"right\" muted>\n              {descriptor ? formatParameterRange(descriptor) : <Unreported />}\n            </Cell>\n            <Cell align=\"right\" muted>\n              {descriptor ? defaultAudioModuleFaceValue(descriptor) : <Unreported />}\n            </Cell>\n            <Cell muted>\n              <ParameterTaper descriptor={descriptor} />\n            </Cell>\n            <Cell muted>{live?.lastSource ?? <Unreported />}</Cell>\n            <Cell>\n              {live?.editing ? (\n                <span style={{ color: toneColor(\"info\") }}>editing</span>\n              ) : (\n                <span style={{ color: token.textMuted }}>—</span>\n              )}\n            </Cell>\n          </>\n        )}\n      />\n    </Section>\n  )\n}\n\nexport const ParametersTab = memo(ParametersTabImpl)\n\n// --- Presets / State ---------------------------------------------------------\n\nexport interface PresetsTabProps {\n  readonly presets: DiagnosticPresetSnapshot | undefined\n  readonly capabilities: DiagnosticCapabilities | undefined\n  readonly stateBudget: number | undefined\n  readonly state: Readonly<Record<string, unknown>> | undefined\n  readonly session: DiagnosticSession\n}\n\nfunction PresetsTabImpl({\n  presets,\n  capabilities,\n  stateBudget,\n  state,\n  session,\n}: PresetsTabProps) {\n  const available = commandUnavailableReason(\"preset\", commands(capabilities))\n  return (\n    <>\n      <Section title=\"Preset state\">\n        <Field label=\"Current\" value={presets?.currentName ?? presets?.currentId} />\n        <Field label=\"Current id\" value={presets?.currentId} />\n        <Field label=\"Dirty\" value={presets?.dirty} />\n        <Field label=\"Factory presets\" value={presets?.factoryCount} />\n        <Field label=\"User presets\" value={presets?.userPresetsSupported} />\n        <Field label=\"Last state size\" value={presets?.lastStateBytes}>\n          {presets?.lastStateBytes === undefined\n            ? undefined\n            : `${formatBytes(presets.lastStateBytes)}${\n                stateBudget === undefined ? \"\" : ` / ${formatBytes(stateBudget)}`\n              }`}\n        </Field>\n      </Section>\n\n      <Section title=\"Actions\">\n        <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 6 }}>\n          {([\"load\", \"save\", \"next\", \"prev\", \"reset\"] as const).map((action) => (\n            <Action\n              key={action}\n              label={action}\n              onClick={() =>\n                session.stimulate({\n                  kind: \"preset\",\n                  action,\n                  ...(action === \"load\" && presets?.currentId\n                    ? { id: presets.currentId }\n                    : {}),\n                })\n              }\n              disabledReason={available}\n            />\n          ))}\n        </div>\n      </Section>\n\n      <Section title=\"Factory bank\">\n        <Table\n          head={[\"Id\", \"Name\"]}\n          empty=\"No factory bank in this host's hello.\"\n          caption=\"Factory presets this host declared.\"\n        >\n          {(presets?.factory ?? []).map((preset) => (\n            <tr key={preset.id}>\n              <Cell muted>{preset.id}</Cell>\n              <Cell>{preset.name}</Cell>\n            </tr>\n          ))}\n        </Table>\n      </Section>\n\n      <Section title=\"Host state\">\n        <Field\n          label=\"maru.state\"\n          value={state ? undefined : null}\n          description=\"The most recent opaque state document this host published.\"\n        >\n          {state ? (\n            <span style={{ fontFamily: token.fontMono, fontSize: 11 }}>\n              {Object.keys(state).length} key(s)\n            </span>\n          ) : undefined}\n        </Field>\n      </Section>\n    </>\n  )\n}\n\nexport const PresetsTab = memo(PresetsTabImpl)\n\n// --- Sampler (MOD-088) -------------------------------------------------------\n\n/**\n * What a sampler-shaped shell loaded, and what went wrong doing it.\n *\n * Built entirely from feeds that already exist: the hello's `banks` table, the\n * `bank` block of `presetState`, the `counters` feed's voice count, the\n * `lifecycle` feed (where the resolver's `bankResolved` / `bankMissing` /\n * `bankHashMismatch` arrive as `runtimeDiagnostic` events), and the face-owned\n * `runtimeStatus` prop. No `sampler` feed was added, and therefore no native\n * wire, conformance-fixture feed list or session snapshot had to grow one.\n *\n * The tab is only reachable when the hello declared `banks` at all\n * (`visibleDiagnosticTabs`), so it is never a page of Unreported cells on a\n * synth.\n */\nexport interface SamplerTabProps {\n  /** The hello bank table, in `kit.bank` order — index IS the param value. */\n  readonly banks: readonly DiagnosticBankInfo[] | undefined\n  readonly presets: DiagnosticPresetSnapshot | undefined\n  readonly counters: DiagnosticCounters | undefined\n  readonly lifecycle: readonly DiagnosticLifecycleEvent[]\n  /** The face's own async load progress; absent on a host that reports none. */\n  readonly runtimeStatus: ModuleFaceRuntimeStatusLike | undefined\n  readonly capabilities: DiagnosticCapabilities | undefined\n  readonly session: DiagnosticSession\n}\n\n/** The subset of `ModuleFaceProps[\"runtimeStatus\"]` this tab reads. Structural\n *  rather than imported so ui-kit keeps no dependency on the face contract. */\nexport interface ModuleFaceRuntimeStatusLike {\n  readonly phase?: string\n  readonly loaded?: number\n  readonly total?: number\n  readonly file?: string\n  readonly error?: string\n}\n\nfunction SamplerTabImpl({\n  banks,\n  presets,\n  counters,\n  lifecycle,\n  runtimeStatus,\n  capabilities,\n  session,\n}: SamplerTabProps) {\n  const bank = presets?.bank\n  const events = bankEventRows(lifecycle)\n  const progress = bankLoadProgress(runtimeStatus)\n  const newest = lifecycle.at(-1)?.timeMs ?? 0\n  /* `maru.loadBank` (MOD-083) is the stimulus that would reload or advance the\n   * bank. It is NOT a diagnostic command, so it is not in `capabilities`;\n   * until it exists the buttons stay disabled with the reason on them rather\n   * than silently doing nothing. */\n  const loadBankReason = commandUnavailableReason(\"preset\", commands(capabilities))\n  /* Voice count reaches the panel through the counters feed's `voiceCount`\n   * (DIAG-007's `SignalTap::setVoiceCount()` seam) when the kernel exposes one;\n   * a kernel that does not leaves it absent, and absent is not zero. */\n  const voiceCount =\n    bank?.voiceCount ??\n    (counters as { readonly voiceCount?: number } | undefined)?.voiceCount\n\n  return (\n    <>\n      <Section title=\"Loaded bank\">\n        {bank === undefined ? (\n          <EmptyFeed reason=\"This host reports no loaded bank. `presetState.bank` was absent from its hello and from every presetState frame — which is different from a bank that failed to load; a failure would appear under Resolution events below.\" />\n        ) : null}\n        <Field label=\"Bank\" value={bank?.name ?? bank?.id} />\n        <Field label=\"Bank id\" value={bank?.id} />\n        <Field label=\"Kind\" value={bank?.kind} />\n        <Field label=\"Version\" value={bank?.version} />\n        <Field\n          label=\"Manifest hash\"\n          value={bank?.sha256}\n          description={bank?.sha256 ?? \"This bank's format declares no manifest hash.\"}\n        >\n          {bank?.sha256 === undefined ? undefined : formatBankHash(bank.sha256)}\n        </Field>\n        <Field\n          label=\"Resolution source\"\n          value={bank?.source}\n          description=\"Where the resolver actually found this bank — reported by MOD-084, never inferred.\"\n        />\n        <Field label=\"Bank index\" value={bank?.index} />\n        <Field label=\"Instrument\" value={bank?.entryName ?? bank?.entryId} />\n        <Field label=\"Instrument id\" value={bank?.entryId} />\n        <Field label=\"Load error\" value={bank?.loadError}>\n          {bank?.loadError === undefined ? undefined : (\n            <span style={{ color: toneColor(\"bad\") }}>{bank.loadError}</span>\n          )}\n        </Field>\n      </Section>\n\n      <Section title=\"Mapping\">\n        <Field label=\"Zones\" value={bank?.zoneCount} />\n        <Field label=\"Velocity layers\" value={bank?.velocityLayers} />\n        <Field label=\"Round-robin groups\" value={bank?.roundRobinGroups} />\n        <Field label=\"Choke groups\" value={bank?.chokeGroups} />\n        <Field label=\"Pads\" value={bank?.padCount} />\n        <Field\n          label=\"Voices sounding\"\n          value={voiceCount}\n          description=\"From the counters feed when this kernel exposes a voice count; absent otherwise, which is not zero.\"\n        />\n      </Section>\n\n      <Section title=\"Assets\">\n        <Field label=\"Loaded\" value={bank?.assetsLoaded}>\n          {bank?.assetsLoaded === undefined ? undefined : (\n            <>\n              {formatNumber(bank.assetsLoaded)}\n              {bank.assetsTotal === undefined ? \"\" : ` / ${formatNumber(bank.assetsTotal)}`}\n            </>\n          )}\n        </Field>\n        <Field label=\"Bytes resident\" value={bank?.bytesResident}>\n          {bank?.bytesResident === undefined ? undefined : formatBytes(bank.bytesResident)}\n        </Field>\n        <Field\n          label=\"Streaming\"\n          value={bank?.streaming}\n          description=\"Preload versus streaming. Stays Unreported until a host actually implements streaming (MOD-049) — the panel does not guess.\"\n        >\n          {bank?.streaming === undefined\n            ? undefined\n            : bank.streaming\n              ? \"streaming\"\n              : \"preload\"}\n        </Field>\n        <Field\n          label=\"Load phase\"\n          value={progress?.phase}\n          description=\"The face's own runtimeStatus, which is host-owned async load progress rather than a diagnostic feed.\"\n        />\n        <Field label=\"Load progress\" value={progress?.loaded}>\n          {progress?.loaded === undefined ? undefined : (\n            <>\n              {formatNumber(progress.loaded)}\n              {progress.total === undefined ? \"\" : ` / ${formatNumber(progress.total)}`}\n            </>\n          )}\n        </Field>\n        <Field label=\"Current file\" value={progress?.file} />\n        <Field label=\"Load status error\" value={progress?.error}>\n          {progress?.error === undefined ? undefined : (\n            <span style={{ color: toneColor(\"bad\") }}>{progress.error}</span>\n          )}\n        </Field>\n      </Section>\n\n      <Section\n        title=\"Banks\"\n        actions={\n          <div style={{ display: \"flex\", gap: 6 }}>\n            <Action\n              label=\"Reload bank\"\n              onClick={() => session.stimulate({ kind: \"preset\", action: \"load\" })}\n              disabledReason={loadBankReason}\n              description=\"Reloads the current bank once maru.loadBank (MOD-083) exists.\"\n            />\n            <Action\n              label=\"Next bank\"\n              onClick={() => session.stimulate({ kind: \"preset\", action: \"next\" })}\n              disabledReason={loadBankReason}\n              description=\"Advances the kit.bank selector once maru.loadBank (MOD-083) exists.\"\n            />\n          </div>\n        }\n      >\n        <Table\n          head={[\"#\", \"Id\", \"Kind\", \"Version\", \"Hash\", \"Source\", \"Zones\"]}\n          empty=\"This host declared an empty bank table: it is a sampler with no banks installed.\"\n          caption=\"Every bank this shell can load, in kit.bank parameter order.\"\n        >\n          {(banks ?? []).map((entry, index) => (\n            <tr key={`${entry.id}-${index}`}>\n              <Cell muted align=\"right\">\n                {index}\n              </Cell>\n              <Cell>{entry.name ?? entry.id}</Cell>\n              <Cell muted>{entry.kind ?? <Unreported />}</Cell>\n              <Cell muted>{entry.version ?? <Unreported />}</Cell>\n              <Cell muted>\n                {entry.sha256 === undefined ? <Unreported /> : formatBankHash(entry.sha256)}\n              </Cell>\n              <Cell muted>{entry.source ?? <Unreported />}</Cell>\n              <Cell align=\"right\">\n                {entry.zoneCount === undefined ? <Unreported /> : formatNumber(entry.zoneCount)}\n              </Cell>\n            </tr>\n          ))}\n        </Table>\n      </Section>\n\n      <Section title=\"Resolution events\">\n        <Table\n          head={[\"When\", \"Event\", \"Bank\", \"Reason\"]}\n          empty=\"No bank resolution events in this host's lifecycle log.\"\n          caption=\"bankResolved, bankMissing, bankHashMismatch and asset load failures, newest first.\"\n        >\n          {events.map((row) => (\n            <tr key={row.seq}>\n              <Cell muted>{formatRelativeEventTime(row.timeMs, newest)}</Cell>\n              <Cell>\n                <span style={{ color: toneColor(row.tone) }}>{row.event}</span>\n              </Cell>\n              <Cell muted>{row.bankId ?? <Unreported />}</Cell>\n              <Cell>{row.reason ?? <Unreported />}</Cell>\n            </tr>\n          ))}\n        </Table>\n      </Section>\n    </>\n  )\n}\n\nexport const SamplerTab = memo(SamplerTabImpl)\n\n// --- Performance -------------------------------------------------------------\n\nexport interface PerformanceTabProps {\n  readonly counters: DiagnosticCounters | undefined\n  readonly capabilities: DiagnosticCapabilities | undefined\n  readonly dropped: DiagnosticSnapshot[\"dropped\"]\n  readonly session: DiagnosticSession\n}\n\nfunction PerformanceTabImpl({\n  counters,\n  capabilities,\n  dropped,\n  session,\n}: PerformanceTabProps) {\n  const rows = counterRows(counters)\n  const load = counters?.loadPercent\n  return (\n    <>\n      <Section\n        title=\"Counters\"\n        actions={\n          <Action\n            label=\"Reset\"\n            onClick={() => session.stimulate({ kind: \"resetCounters\" })}\n            disabledReason={commandUnavailableReason(\n              \"resetCounters\",\n              commands(capabilities)\n            )}\n          />\n        }\n      >\n        {counters === undefined ? (\n          <EmptyFeed reason=\"This host does not report the counters feed. Callback timings, deadline misses and drop counts are unknown.\" />\n        ) : null}\n        <Field label=\"Window opened at frame\" value={counters?.since} />\n        <Field label=\"CPU load\" value={load}>\n          {load === undefined ? undefined : (\n            <span style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n              <span\n                aria-hidden\n                style={{\n                  position: \"relative\",\n                  flex: \"0 0 96px\",\n                  height: 6,\n                  borderRadius: 3,\n                  background: token.track,\n                  overflow: \"hidden\",\n                }}\n              >\n                <span\n                  style={{\n                    position: \"absolute\",\n                    inset: 0,\n                    width: `${Math.max(0, Math.min(100, load))}%`,\n                    background:\n                      load >= 90\n                        ? toneColor(\"bad\")\n                        : load >= 60\n                          ? toneColor(\"warn\")\n                          : token.accent,\n                  }}\n                />\n              </span>\n              <Numeric width={7}>{`${formatNumber(load)} %`}</Numeric>\n            </span>\n          )}\n        </Field>\n      </Section>\n\n      <Section title=\"All counters\">\n        <Table head={[\"Counter\", \"Value\"]} caption=\"Developer counters for this window.\">\n          {rows.map((row) => (\n            <tr key={row.key} aria-description={row.title}>\n              <Cell muted>{row.label}</Cell>\n              <Cell align=\"right\">\n                {row.value === UNREPORTED_LABEL ? (\n                  <Unreported />\n                ) : (\n                  <Numeric width={12} tone={row.tone}>\n                    {row.value}\n                  </Numeric>\n                )}\n              </Cell>\n            </tr>\n          ))}\n        </Table>\n      </Section>\n\n      <Section title=\"Session drops\">\n        <Field label=\"Feed frames\">{formatMaybe(dropped.feeds)}</Field>\n        <Field label=\"MIDI events\">{formatMaybe(dropped.midi)}</Field>\n        <Field label=\"Lifecycle events\">{formatMaybe(dropped.lifecycle)}</Field>\n      </Section>\n    </>\n  )\n}\n\nexport const PerformanceTab = memo(PerformanceTabImpl)\n\n/** Feeds a tab needs, for the \"this host does not report X\" line. */\nexport function missingFeeds(\n  needed: readonly DiagnosticFeed[],\n  capabilities: DiagnosticCapabilities | undefined\n): readonly DiagnosticFeed[] {\n  if (!capabilities) return needed\n  return needed.filter((feed) => !capabilities.feeds.includes(feed))\n}\n",
      "type": "registry:component",
      "target": "@ui/diagnostic-tabs-info.tsx"
    },
    {
      "path": "components/ui/diagnostic-tabs-live.tsx",
      "content": "/**\n * Source: https://maru.audio/ui-kit/diagnostic-panel\n * Copyright © [Maru](https://maru.audio)\n *\n * Maru UI Kit — https://maru.audio/ui-kit\n *\n * Installed from the Maru UI registry. This file is yours now: edit it\n * freely, it will not be overwritten unless you re-run the add command.\n *\n * Keep this item’s companion files and CSS imports together. Dependencies\n * declared by the registry are installed with the source.\n */\n/**\n * The streaming tabs: Transport/Clock, MIDI, Audio, Events, Stimulus.\n *\n * These read feeds that only arrive while the session is open, so each one\n * distinguishes three states that a careless panel would collapse into one\n * blank: the host cannot produce this feed, the host can but has not sent a\n * frame yet, and the host sent a frame whose value happens to be zero.\n *\n * Like the informational tabs, each takes only the slice of the snapshot it\n * reads and is wrapped in `memo`, so a meters frame at 30 Hz cannot re-render\n * the Events table.\n */\n\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { ppqPerBar } from \"maruaudio/ui/shared/maru/contracts/transport\"\nimport type {\n  DiagnosticCapabilities,\n  DiagnosticChannelLevel,\n  DiagnosticClockFrame,\n  DiagnosticLifecycleEvent,\n  DiagnosticLifecycleKind,\n  DiagnosticMeterFrame,\n  DiagnosticMidiEvent,\n  DiagnosticScopeTap,\n  DiagnosticTestSignal,\n  DiagnosticTransportFrame,\n} from \"maruaudio/ui/shared/maru/contracts\"\nimport type {\n  DiagnosticSession,\n  DiagnosticSnapshot,\n} from \"maruaudio/ui/shared/maru/diagnostic-session\"\n\nimport { token } from \"maruaudio/ui/shared/theme\"\nimport { decodeMidiMessage } from \"maruaudio/ui/shared/midi-message-decode\"\nimport { Goniometer } from \"@/components/ui/goniometer\"\nimport { LevelMeter } from \"@/components/ui/level-meter\"\nimport { Oscilloscope } from \"@/components/ui/oscilloscope\"\nimport { PianoKeyboard } from \"@/components/ui/piano-keyboard\"\nimport { Spectrum } from \"@/components/ui/spectrum\"\nimport {\n  Action,\n  Badge,\n  Cell,\n  EmptyFeed,\n  Field,\n  FilterChip,\n  Numeric,\n  Section,\n  Table,\n  Unreported,\n  WindowedTable,\n  inputStyle,\n  toneColor,\n} from \"@/components/ui/diagnostic-panel-chrome\"\nimport {\n  channelLevelBadge,\n  commandUnavailableReason,\n  filterLifecycle,\n  filterMidi,\n  formatBarBeatTick,\n  formatDb,\n  formatHz,\n  formatNumber,\n  formatRelativeEventTime,\n  lastPresetLoadSeq,\n  lifecycleSeverity,\n  outputClassificationBadge,\n  presentLifecycleKinds,\n  STEREO_VERDICT_DESCRIPTION,\n  stereoVerdict,\n} from \"maruaudio/ui/shared/diagnostic-panel-core\"\nimport { SCOPE_FRAME_SIZE, SPECTRUM_BINS, useScopeDriver } from \"maruaudio/ui/shared/diagnostic-panel-raf\"\n\n// --- Transport / Clock -------------------------------------------------------\n\nexport interface TransportTabProps {\n  readonly transport: DiagnosticTransportFrame | undefined\n  readonly clock: DiagnosticClockFrame | undefined\n  readonly capabilities: DiagnosticCapabilities | undefined\n  readonly session: DiagnosticSession\n}\n\nfunction TransportTabImpl({\n  transport: frame,\n  clock,\n  capabilities,\n  session,\n}: TransportTabProps) {\n  const state = frame?.state\n  const caps = frame?.capabilities\n  const beatsPerBar = state ? ppqPerBar(state.timeSignature) : 4\n  const canTransport = commandUnavailableReason(\"transport\", capabilities?.commands)\n\n  return (\n    <>\n      <Section title=\"Transport\">\n        {frame ? null : (\n          <EmptyFeed reason=\"No transport frame. This host reports no transport — tempo, position and loop are unknown, not stopped at zero.\" />\n        )}\n        <Field label=\"Source\" value={frame?.source} />\n        <Field label=\"Playing\" value={state?.playing} />\n        <Field label=\"Recording\" value={state?.recording} />\n        <Field label=\"Looping\" value={state?.looping} />\n        <Field label=\"Tempo\" value={state?.tempo}>\n          {state ? <Numeric width={9}>{`${formatNumber(state.tempo)} bpm`}</Numeric> : undefined}\n        </Field>\n        <Field label=\"Time signature\" value={state?.timeSignature}>\n          {state\n            ? `${state.timeSignature.numerator}/${state.timeSignature.denominator}`\n            : undefined}\n        </Field>\n        <Field\n          label=\"Position\"\n          value={state?.ppqPosition}\n          description=\"bars|beats|ticks at 960 ticks per quarter note.\"\n        >\n          {state ? (\n            <Numeric width={12}>{formatBarBeatTick(state.ppqPosition, beatsPerBar)}</Numeric>\n          ) : undefined}\n        </Field>\n        <Field label=\"PPQ position\" value={state?.ppqPosition}>\n          {state ? <Numeric width={10}>{formatNumber(state.ppqPosition)}</Numeric> : undefined}\n        </Field>\n        <Field label=\"Bar downbeat PPQ\" value={state?.barPositionPpq} />\n        <Field label=\"Loop start\" value={state?.loopStartPpq} />\n        <Field label=\"Loop end\" value={state?.loopEndPpq} />\n        <Field label=\"Sample rate\" value={state?.sampleRate}>\n          {state?.sampleRate == null ? undefined : formatHz(state.sampleRate)}\n        </Field>\n        <Field label=\"Project samples\" value={state?.projectTimeSamples} />\n        <Field label=\"At frame\" value={frame?.atFrame} />\n      </Section>\n\n      <Section title=\"Capabilities\">\n        <Field label=\"Reports tempo\" value={caps?.tempo} />\n        <Field label=\"Reports time signature\" value={caps?.timeSignature} />\n        <Field label=\"Reports position\" value={caps?.position} />\n        <Field label=\"Reports loop\" value={caps?.loop} />\n        <Field label=\"Accepts tempo\" value={caps?.canSetTempo} />\n      </Section>\n\n      <Section title=\"Internal clock\">\n        {clock ? (\n          <>\n            <Field label=\"Source\" value={clock.source} />\n            <Field label=\"Running\" value={clock.running} />\n            <Field label=\"Tempo\" value={clock.bpm}>{`${formatNumber(clock.bpm)} bpm`}</Field>\n            <Field label=\"Bar\" value={clock.bar} />\n            <Field label=\"Beat\" value={clock.beat} />\n            <Field label=\"Step\" value={clock.step} />\n            <Field label=\"Steps per bar\" value={clock.stepsPerBar} />\n            <Field label=\"Phase\" value={clock.phase}>\n              <span style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n                <span\n                  aria-hidden\n                  style={{\n                    width: 10,\n                    height: 10,\n                    borderRadius: \"50%\",\n                    background: clock.phase < 0.25 ? token.accent : token.track,\n                  }}\n                />\n                <Numeric width={6}>{formatNumber(clock.phase)}</Numeric>\n              </span>\n            </Field>\n          </>\n        ) : (\n          <EmptyFeed reason=\"This module reports no internal clock.\" />\n        )}\n      </Section>\n\n      <Section title=\"Control\">\n        <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 6 }}>\n          <Action\n            label=\"Play\"\n            onClick={() => session.stimulate({ kind: \"transport\", action: \"play\" })}\n            disabledReason={canTransport}\n          />\n          <Action\n            label=\"Stop\"\n            onClick={() => session.stimulate({ kind: \"transport\", action: \"stop\" })}\n            disabledReason={canTransport}\n          />\n          <Action\n            label=\"Locate 0\"\n            onClick={() => session.stimulate({ kind: \"transport\", action: \"locate\", ppq: 0 })}\n            disabledReason={canTransport}\n          />\n          <Action\n            label=\"Tempo 120\"\n            onClick={() =>\n              session.stimulate({ kind: \"transport\", action: \"setTempo\", tempo: 120 })\n            }\n            disabledReason={\n              canTransport ??\n              (caps && !caps.canSetTempo\n                ? \"This host owns the tempo map and ignores tempo writes.\"\n                : null)\n            }\n          />\n        </div>\n      </Section>\n    </>\n  )\n}\n\nexport const TransportTab = memo(TransportTabImpl)\n\n// --- MIDI --------------------------------------------------------------------\n\nfunction MidiTable({\n  events,\n  empty,\n  caption,\n}: {\n  readonly events: readonly DiagnosticMidiEvent[]\n  readonly empty: string\n  readonly caption: string\n}) {\n  return (\n    <WindowedTable\n      head={[\"Seq\", \"Frame\", \"Off\", \"Ch\", \"Kind\", \"Message\", \"Src\"]}\n      rows={events}\n      rowKey={(event) => `${event.direction}:${event.seq}`}\n      empty={empty}\n      caption={caption}\n      height={260}\n      renderRow={(event) => {\n        const decoded = decodeMidiMessage(event.data)\n        const isSystem =\n          decoded.kind === \"sysex\" ||\n          decoded.kind === \"timingClock\" ||\n          decoded.kind === \"systemRealTime\"\n        return (\n          <>\n            <Cell muted>\n              <Numeric width={5}>{event.seq}</Numeric>\n            </Cell>\n            <Cell align=\"right\" muted>\n              <Numeric width={9}>{formatNumber(event.atFrame)}</Numeric>\n            </Cell>\n            <Cell align=\"right\" muted>\n              <Numeric width={5}>{formatNumber(event.offset)}</Numeric>\n            </Cell>\n            <Cell align=\"right\">\n              <Numeric width={3}>{isSystem ? \"—\" : decoded.channel + 1}</Numeric>\n            </Cell>\n            <Cell>{decoded.kind}</Cell>\n            <Cell>{decoded.description}</Cell>\n            <Cell muted>{event.source ?? <Unreported />}</Cell>\n          </>\n        )\n      }}\n    />\n  )\n}\n\nfunction MidiTabImpl({ midi }: { readonly midi: DiagnosticSnapshot[\"midi\"] }) {\n  const [query, setQuery] = useState(\"\")\n  const [hideRealtime, setHideRealtime] = useState(false)\n  const filter = useMemo(() => ({ query, hideRealtime }), [query, hideRealtime])\n  const incoming = useMemo(() => filterMidi(midi.in, filter), [midi.in, filter])\n  const outgoing = useMemo(() => filterMidi(midi.out, filter), [midi.out, filter])\n\n  // The note keyboard shows what is currently held, derived from the in ring.\n  const held = useMemo(() => {\n    const map = new Map<number, boolean>()\n    for (const event of midi.in) {\n      const decoded = decodeMidiMessage(event.data)\n      if (decoded.note === undefined) continue\n      if (decoded.kind === \"noteOn\") map.set(decoded.note, true)\n      else if (decoded.kind === \"noteOff\") map.delete(decoded.note)\n    }\n    return map\n  }, [midi.in])\n\n  return (\n    <>\n      <Section title=\"Filter\">\n        <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 8, alignItems: \"center\" }}>\n          <input\n            style={{ ...inputStyle, flex: \"1 1 8rem\" }}\n            placeholder=\"port, source or byte\"\n            value={query}\n            onChange={(event) => setQuery(event.target.value)}\n            aria-label=\"Filter MIDI events\"\n          />\n          <label style={{ display: \"flex\", alignItems: \"center\", gap: 4, fontSize: 11 }}>\n            <input\n              type=\"checkbox\"\n              checked={hideRealtime}\n              onChange={(event) => setHideRealtime(event.target.checked)}\n            />\n            Hide realtime bytes\n          </label>\n        </div>\n      </Section>\n\n      <Section title=\"Held notes\">\n        <PianoKeyboard startNote={36} octaves={3} held={held} height={54} />\n      </Section>\n\n      <Section title={`MIDI in (${incoming.length})`}>\n        <MidiTable\n          events={incoming}\n          caption=\"Inbound MIDI, newest first.\"\n          empty={\n            midi.in.length\n              ? \"Every event filtered out.\"\n              : \"No MIDI in. Either nothing arrived or this host does not report the midiIn feed.\"\n          }\n        />\n      </Section>\n\n      <Section title={`MIDI out (${outgoing.length})`}>\n        <MidiTable\n          events={outgoing}\n          caption=\"Outbound MIDI, newest first.\"\n          empty={\n            midi.out.length\n              ? \"Every event filtered out.\"\n              : \"No MIDI out. Either the module emits none or this host does not report the midiOut feed.\"\n          }\n        />\n      </Section>\n    </>\n  )\n}\n\nexport const MidiTab = memo(MidiTabImpl)\n\n// --- Audio -------------------------------------------------------------------\n\nconst SCOPE_TAPS: readonly DiagnosticScopeTap[] = [\"input\", \"output\", \"wet\"]\n\n/**\n * Input and output side by side, per channel.\n *\n * The field report's question is \"is the effect doing anything\", and the only\n * way to answer that at a glance is to see the two buses together — a column\n * of input meters above a column of output meters makes the eye travel, and\n * the comparison is the whole point.\n */\nfunction BusMeters({\n  title,\n  channels,\n  compact = false,\n}: {\n  readonly title: string\n  readonly channels: readonly DiagnosticChannelLevel[] | undefined\n  readonly compact?: boolean\n}) {\n  if (!channels || channels.length === 0)\n    return (\n      <div style={{ minWidth: 0 }}>\n        <BusHeading title={title} />\n        <EmptyFeed reason=\"Not reported by this host.\" />\n      </div>\n    )\n  return (\n    <div style={{ minWidth: 0 }}>\n      <BusHeading title={title} />\n      <div style={{ display: \"flex\", gap: 8, alignItems: \"flex-end\" }}>\n        {channels.map((channel, index) => (\n          <div key={index} style={{ display: \"grid\", gap: 3, justifyItems: \"center\" }}>\n            <LevelMeter\n              value={[Math.max(0, Math.min(1, channel.peak))]}\n              channels={1}\n              orientation=\"vertical\"\n              length={compact ? 56 : 72}\n              thickness={11}\n              showScale={false}\n            />\n            <span\n              style={{ fontFamily: token.fontMono, fontSize: 10, color: token.textMuted }}\n            >\n              {index === 0 ? \"L\" : index === 1 ? \"R\" : index + 1}\n            </span>\n            <Badge badge={channelLevelBadge(channel)} />\n          </div>\n        ))}\n        <div style={{ flex: \"1 1 8rem\", minWidth: 0 }}>\n          <Table head={[\"Ch\", \"Peak\", \"RMS\"]} caption={`${title} levels per channel.`}>\n            {channels.map((channel, index) => (\n              <tr key={index}>\n                <Cell muted>{index}</Cell>\n                <Cell align=\"right\">\n                  <Numeric width={9}>{formatDb(channel.peak)}</Numeric>\n                </Cell>\n                <Cell align=\"right\">\n                  <Numeric width={9}>{formatDb(channel.rms)}</Numeric>\n                </Cell>\n              </tr>\n            ))}\n          </Table>\n        </div>\n      </div>\n    </div>\n  )\n}\n\nfunction BusHeading({ title }: { readonly title: string }) {\n  return (\n    <h4\n      style={{\n        margin: \"0 0 6px\",\n        fontSize: 10,\n        fontWeight: 600,\n        letterSpacing: \"0.08em\",\n        textTransform: \"uppercase\",\n        color: token.textMuted,\n      }}\n    >\n      {title}\n    </h4>\n  )\n}\n\nexport interface AudioTabProps {\n  readonly meters: DiagnosticMeterFrame | undefined\n  readonly capabilities: DiagnosticCapabilities | undefined\n  readonly sampleRate: number | undefined\n  readonly session: DiagnosticSession\n  readonly live?: boolean\n}\n\n/**\n * The Audio tab.\n *\n * Four viewers on one shared animation frame (see `diagnostic-panel-raf.ts`),\n * laid out as a 2×2 grid once there is room for it and stacked below that. The\n * scope has a trigger level and a single-shot capture, because the transient a\n * developer is chasing is by definition the one that does not repeat: the\n * driver watches for a rising edge through the level and freezes the whole\n * cache on the frame that contains it, so scope, goniometer and spectrum all\n * hold the *same* frame rather than three neighbouring ones.\n */\nfunction AudioTabImpl({\n  meters,\n  capabilities,\n  sampleRate,\n  session,\n  live = true,\n}: AudioTabProps) {\n  const [tap, setTap] = useState<DiagnosticScopeTap>(\"output\")\n  const [wide, setWide] = useState(false)\n  const [triggerLevel, setTriggerLevel] = useState(0)\n  const [armed, setArmed] = useState(false)\n  const gridRef = useRef<HTMLDivElement>(null)\n\n  const { driver, paused } = useScopeDriver(session, live)\n  const [frozen, setFrozen] = useState(false)\n\n  // The 2×2 grid needs about 560 px before the goniometer stops being a\n  // postage stamp; below that the four viewers stack.\n  useEffect(() => {\n    const node = gridRef.current\n    if (!node || typeof ResizeObserver === \"undefined\") return\n    const observer = new ResizeObserver((entries) => {\n      const entry = entries[0]\n      if (entry) setWide(entry.contentRect.width >= 560)\n    })\n    observer.observe(node)\n    setWide(node.getBoundingClientRect().width >= 560)\n    return () => observer.disconnect()\n  }, [])\n\n  const armSingleShot = useCallback(() => {\n    setArmed(true)\n    setFrozen(false)\n    driver.armSingleShot(tap, triggerLevel, () => {\n      setArmed(false)\n      setFrozen(true)\n    })\n  }, [driver, tap, triggerLevel])\n\n  const resume = useCallback(() => {\n    driver.disarm()\n    driver.setFrozen(false)\n    setArmed(false)\n    setFrozen(false)\n  }, [driver])\n\n  const freeze = useCallback(() => {\n    driver.disarm()\n    driver.setFrozen(true)\n    setArmed(false)\n    setFrozen(true)\n  }, [driver])\n\n  // Changing the tap while frozen would show the frozen frame of a tap the\n  // driver never captured; resume instead, which is what a developer means.\n  const selectTap = useCallback(\n    (next: DiagnosticScopeTap) => {\n      setTap(next)\n      resume()\n    },\n    [resume]\n  )\n\n  // Every viewer reads out of the driver's cache rather than out of the\n  // session, so one `readScope` per tap per frame feeds all four.\n  const getStereoData = useCallback(\n    (left: Float32Array, right: Float32Array) => driver.readStereo(tap, left, right),\n    [driver, tap]\n  )\n  const getMonoData = useCallback(\n    (target: Float32Array) => driver.readMono(tap, target),\n    [driver, tap]\n  )\n  const getSpectrumData = useCallback(\n    (target: Float32Array) => driver.readSpectrum(tap, target),\n    [driver, tap]\n  )\n\n  const verdict = stereoVerdict({\n    channels: meters?.output,\n    correlation: meters?.correlation,\n  })\n  const width =\n    meters?.output && meters.output.length > 1 && meters.correlation !== undefined\n      ? Math.round((1 - meters.correlation) * 500) / 1000\n      : undefined\n\n  const testSignalReason = commandUnavailableReason(\"testSignal\", capabilities?.commands)\n\n  return (\n    <>\n      <Section title=\"Signal\">\n        <div\n          style={{\n            display: \"grid\",\n            gap: 10,\n            gridTemplateColumns: wide ? \"1fr 1fr\" : \"1fr\",\n            marginBottom: 10,\n          }}\n        >\n          <BusMeters title=\"Input\" channels={meters?.input} compact />\n          <BusMeters title=\"Output\" channels={meters?.output} compact />\n        </div>\n        {meters?.sidechain ? (\n          <div style={{ marginBottom: 10 }}>\n            <BusMeters title=\"Sidechain\" channels={meters.sidechain} compact />\n          </div>\n        ) : null}\n        <Field label=\"At frame\" value={meters?.atFrame} />\n        <Field label=\"Input class\" value={meters?.classification.input} />\n        <Field label=\"Output class\">\n          <Badge badge={outputClassificationBadge(meters?.classification.output)} />\n        </Field>\n        <Field label=\"Correlation\" value={meters?.correlation}>\n          {meters?.correlation === undefined ? undefined : (\n            <Numeric width={7}>{formatNumber(meters.correlation)}</Numeric>\n          )}\n        </Field>\n        <Field\n          label=\"Width\"\n          value={width}\n          description=\"0 is a mono-summable pair, 1 is fully decorrelated, above 1 is out of phase. Derived from the correlation the host reported.\"\n        >\n          {width === undefined ? undefined : <Numeric width={7}>{formatNumber(width)}</Numeric>}\n        </Field>\n        <Field label=\"Stereo verdict\" description={STEREO_VERDICT_DESCRIPTION[verdict]}>\n          <span style={{ fontFamily: token.fontMono }}>{verdict}</span>\n        </Field>\n      </Section>\n\n      <Section\n        title=\"Viewers\"\n        actions={\n          <div\n            role=\"group\"\n            aria-label=\"Scope tap\"\n            style={{ display: \"flex\", gap: 4 }}\n          >\n            {SCOPE_TAPS.map((candidate) => (\n              <FilterChip\n                key={candidate}\n                label={candidate}\n                active={candidate === tap}\n                onToggle={() => selectTap(candidate)}\n                description={`Read the ${candidate} tap.`}\n              />\n            ))}\n          </div>\n        }\n      >\n        <div\n          style={{\n            display: \"flex\",\n            flexWrap: \"wrap\",\n            gap: 8,\n            alignItems: \"center\",\n            marginBottom: 8,\n          }}\n        >\n          <label style={{ fontSize: 11, color: token.textMuted }}>\n            trigger\n            <input\n              style={{ ...inputStyle, width: \"5rem\", marginLeft: 4 }}\n              type=\"number\"\n              step={0.05}\n              min={-1}\n              max={1}\n              value={triggerLevel}\n              onChange={(event) => setTriggerLevel(Number(event.target.value))}\n              aria-label=\"Trigger level\"\n            />\n          </label>\n          <Action\n            label={armed ? \"Waiting…\" : \"Single shot\"}\n            onClick={armSingleShot}\n            description=\"Freeze every viewer on the next frame that crosses the trigger level rising.\"\n          />\n          {frozen ? (\n            <Action label=\"Resume\" onClick={resume} />\n          ) : (\n            <Action label=\"Freeze\" onClick={freeze} />\n          )}\n          <span\n            role=\"status\"\n            style={{ fontSize: 11, color: frozen ? toneColor(\"info\") : token.textMuted }}\n          >\n            {frozen ? \"frozen\" : armed ? \"armed\" : \"live\"}\n          </span>\n          <Action\n            label=\"Impulse → output\"\n            onClick={() =>\n              session.stimulate({\n                kind: \"testSignal\",\n                signal: \"impulse\",\n                target: \"output\",\n                mode: \"replace\",\n                durationMs: 20,\n                levelDb: -6,\n              })\n            }\n            disabledReason={testSignalReason}\n            description=\"Fire one impulse so the viewers have something unambiguous to show.\"\n          />\n        </div>\n\n        <div\n          ref={gridRef}\n          style={{\n            display: \"grid\",\n            gap: 8,\n            gridTemplateColumns: wide ? \"1fr 1fr\" : \"1fr\",\n          }}\n        >\n          <ViewerCell label={`Scope · ${tap}`}>\n            <Oscilloscope\n              getData={getMonoData}\n              dataSize={SCOPE_FRAME_SIZE}\n              height={110}\n              trigger\n              paused={paused || frozen}\n              aria-label={`Oscilloscope of the ${tap} tap`}\n            />\n          </ViewerCell>\n          <ViewerCell label=\"Goniometer\">\n            <Goniometer\n              getStereoData={getStereoData}\n              dataSize={SCOPE_FRAME_SIZE}\n              height={110}\n              paused={paused || frozen}\n              aria-label={`Goniometer of the ${tap} tap`}\n            />\n          </ViewerCell>\n          <ViewerCell label=\"Spectrum\">\n            <Spectrum\n              getData={getSpectrumData}\n              dataSize={SPECTRUM_BINS}\n              height={110}\n              sampleRate={sampleRate}\n              paused={paused || frozen}\n              aria-label={`Spectrum of the ${tap} tap`}\n            />\n          </ViewerCell>\n          <ViewerCell label=\"Output meters\">\n            <div\n              style={{\n                display: \"flex\",\n                gap: 10,\n                alignItems: \"flex-end\",\n                justifyContent: \"center\",\n                height: 110,\n              }}\n            >\n              {(meters?.output ?? []).map((channel, index) => (\n                <div key={index} style={{ display: \"grid\", gap: 3, justifyItems: \"center\" }}>\n                  <LevelMeter\n                    value={[Math.max(0, Math.min(1, channel.peak))]}\n                    channels={1}\n                    orientation=\"vertical\"\n                    length={84}\n                    thickness={13}\n                    showScale={false}\n                  />\n                  <span\n                    style={{\n                      fontFamily: token.fontMono,\n                      fontSize: 10,\n                      color: token.textMuted,\n                    }}\n                  >\n                    {index === 0 ? \"L\" : index === 1 ? \"R\" : index + 1}\n                  </span>\n                </div>\n              ))}\n              {meters?.output ? null : (\n                <span style={{ color: token.textMuted, fontSize: 11 }}>\n                  No meter frame.\n                </span>\n              )}\n            </div>\n          </ViewerCell>\n        </div>\n      </Section>\n    </>\n  )\n}\n\nfunction ViewerCell({\n  label,\n  children,\n}: {\n  readonly label: string\n  readonly children: React.ReactNode\n}) {\n  return (\n    <figure style={{ margin: 0, minWidth: 0 }}>\n      <figcaption\n        style={{\n          fontFamily: token.fontMono,\n          fontSize: 10,\n          color: token.textMuted,\n          marginBottom: 3,\n        }}\n      >\n        {label}\n      </figcaption>\n      {children}\n    </figure>\n  )\n}\n\nexport const AudioTab = memo(AudioTabImpl)\n\n// --- Events ------------------------------------------------------------------\n\nfunction EventsTabImpl({\n  lifecycle,\n}: {\n  readonly lifecycle: readonly DiagnosticLifecycleEvent[]\n}) {\n  const [query, setQuery] = useState(\"\")\n  const [kinds, setKinds] = useState<readonly DiagnosticLifecycleKind[]>([])\n  const [sincePreset, setSincePreset] = useState(false)\n  const [copied, setCopied] = useState<\"idle\" | \"all\" | \"none\">(\"idle\")\n\n  const present = useMemo(() => presentLifecycleKinds(lifecycle), [lifecycle])\n  const presetSeq = useMemo(() => lastPresetLoadSeq(lifecycle), [lifecycle])\n\n  const events = useMemo(() => {\n    const filtered = filterLifecycle(lifecycle, { query, kinds })\n    if (!sincePreset || presetSeq === null) return filtered\n    return filtered.filter((event) => event.seq >= presetSeq)\n  }, [lifecycle, query, kinds, sincePreset, presetSeq])\n\n  // \"Now\" in a log with no wall clock is the newest event, so relative times\n  // are measured against it rather than against the panel's own clock — the\n  // host's `timeMs` is milliseconds since ITS activation and the two clocks\n  // share no origin.\n  const newestMs = useMemo(\n    () => lifecycle.reduce((max, event) => Math.max(max, event.timeMs), 0),\n    [lifecycle]\n  )\n\n  const copySelection = useCallback(() => {\n    void writeClipboard(JSON.stringify(events, null, 2)).then((ok) => {\n      setCopied(ok ? \"all\" : \"none\")\n      if (typeof window !== \"undefined\")\n        window.setTimeout(() => setCopied(\"idle\"), 1500)\n    })\n  }, [events])\n\n  return (\n    <>\n      <Section\n        title=\"Filter\"\n        actions={\n          <Action\n            label={\n              copied === \"all\"\n                ? `Copied ${events.length}`\n                : copied === \"none\"\n                  ? \"Copy failed\"\n                  : `Copy ${events.length} as JSON`\n            }\n            onClick={copySelection}\n            description=\"Copies exactly the rows this filter is showing, in wire order.\"\n          />\n        }\n      >\n        <input\n          style={{ ...inputStyle, width: \"100%\" }}\n          placeholder=\"kind, detail key or value\"\n          value={query}\n          onChange={(event) => setQuery(event.target.value)}\n          aria-label=\"Filter lifecycle events\"\n        />\n        <div\n          role=\"group\"\n          aria-label=\"Event kind filters\"\n          style={{ display: \"flex\", flexWrap: \"wrap\", gap: 4, marginTop: 6 }}\n        >\n          <FilterChip\n            label={\n              presetSeq === null ? \"since preset load (none)\" : \"since last preset load\"\n            }\n            active={sincePreset}\n            onToggle={() => setSincePreset((current) => !current)}\n            tone=\"info\"\n            description={\n              presetSeq === null\n                ? \"No presetLoaded event in this log yet.\"\n                : `Hides everything before seq ${presetSeq}, the newest preset recall.`\n            }\n          />\n          {present.map((kind) => (\n            <FilterChip\n              key={kind}\n              label={kind}\n              active={kinds.includes(kind)}\n              tone={lifecycleSeverity(kind)}\n              onToggle={() =>\n                setKinds((current) =>\n                  current.includes(kind)\n                    ? current.filter((entry) => entry !== kind)\n                    : [...current, kind]\n                )\n              }\n            />\n          ))}\n        </div>\n      </Section>\n\n      <Section title={`Timeline (${events.length})`}>\n        <WindowedTable\n          head={[\"Seq\", \"Age\", \"Frame\", \"Kind\", \"Detail\"]}\n          rows={events}\n          rowKey={(event) => event.seq}\n          height={320}\n          caption=\"Lifecycle events, newest first, aged against the newest one.\"\n          empty={\n            lifecycle.length\n              ? \"Every event filtered out.\"\n              : \"No lifecycle events. This host does not report the lifecycle feed.\"\n          }\n          renderRow={(event) => {\n            const tone = lifecycleSeverity(event.kind)\n            return (\n              <>\n                <Cell muted>\n                  <Numeric width={5}>{event.seq}</Numeric>\n                </Cell>\n                <Cell align=\"right\" muted>\n                  <Numeric width={9} description={`${formatNumber(event.timeMs)} ms since activation`}>\n                    {formatRelativeEventTime(event.timeMs, newestMs)}\n                  </Numeric>\n                </Cell>\n                <Cell align=\"right\" muted>\n                  <Numeric width={9}>\n                    {event.atFrame === undefined ? (\n                      <Unreported />\n                    ) : (\n                      formatNumber(event.atFrame)\n                    )}\n                  </Numeric>\n                </Cell>\n                <Cell>\n                  <span style={{ color: tone === \"neutral\" ? token.text : toneColor(tone) }}>\n                    {event.kind}\n                  </span>\n                </Cell>\n                <Cell muted>\n                  {event.detail\n                    ? Object.entries(event.detail)\n                        .map(([key, value]) => `${key}=${String(value)}`)\n                        .join(\" \")\n                    : \"—\"}\n                </Cell>\n              </>\n            )\n          }}\n        />\n      </Section>\n    </>\n  )\n}\n\nexport const EventsTab = memo(EventsTabImpl)\n\n// --- Stimulus ----------------------------------------------------------------\n\nconst TEST_SIGNALS: readonly DiagnosticTestSignal[] = [\n  \"sine\",\n  \"impulse\",\n  \"white\",\n  \"pink\",\n  \"sweep\",\n  \"dc\",\n  \"silence\",\n]\n\n/**\n * The one-click presets the task asks for.\n *\n * Every one of them answers a specific question in a single gesture: does\n * anything reach the input, does anything leave the output, does the\n * instrument sound, and does everything stop. Building the same stimulus by\n * hand takes six fields, which is six chances to get it wrong while chasing a\n * bug.\n */\nconst STIMULUS_PRESETS: readonly {\n  readonly id: string\n  readonly label: string\n  readonly title: string\n  readonly command: string\n  readonly build: () => import(\"maruaudio/ui/shared/maru/contracts\").DiagnosticStimulus\n}[] = [\n  {\n    id: \"sine\",\n    label: \"1 kHz −12 dB → input\",\n    title:\n      \"Two seconds of 1 kHz at −12 dBFS replacing the input bus. If the output meters stay dead, the kernel is not passing signal.\",\n    command: \"testSignal\",\n    build: () => ({\n      kind: \"testSignal\",\n      signal: \"sine\",\n      target: \"input\",\n      mode: \"replace\",\n      frequencyHz: 1000,\n      levelDb: -12,\n      durationMs: 2000,\n    }),\n  },\n  {\n    id: \"impulse\",\n    label: \"Impulse → output\",\n    title:\n      \"One impulse written straight to the output bus. It proves the path from here to the speakers without involving the kernel at all.\",\n    command: \"testSignal\",\n    build: () => ({\n      kind: \"testSignal\",\n      signal: \"impulse\",\n      target: \"output\",\n      mode: \"replace\",\n      levelDb: -6,\n      durationMs: 20,\n    }),\n  },\n  {\n    id: \"note\",\n    label: \"C4 note 500 ms\",\n    title: \"Middle C at velocity 100, released after half a second.\",\n    command: \"injectMidi\",\n    build: () => ({\n      kind: \"injectMidi\",\n      events: [{ offset: 0, data: [0x90, 60, 100] }],\n    }),\n  },\n  {\n    id: \"panic\",\n    label: \"Panic\",\n    title: \"All notes off, every channel.\",\n    command: \"panic\",\n    build: () => ({ kind: \"panic\" }),\n  },\n]\n\nfunction StimulusTabImpl({\n  capabilities,\n  session,\n}: {\n  readonly capabilities: DiagnosticCapabilities | undefined\n  readonly session: DiagnosticSession\n}) {\n  const commands = capabilities?.commands\n  const injectReason = commandUnavailableReason(\"injectMidi\", commands)\n  const signalReason = commandUnavailableReason(\"testSignal\", commands)\n  const panicReason = commandUnavailableReason(\"panic\", commands)\n  const transportReason = commandUnavailableReason(\"transport\", commands)\n\n  const [status, setStatus] = useState(0)\n  const [data1, setData1] = useState(60)\n  const [data2, setData2] = useState(100)\n  const [signal, setSignal] = useState<DiagnosticTestSignal>(\"sine\")\n  const [target, setTarget] = useState<\"input\" | \"output\" | \"sidechain\">(\"input\")\n  const [mode, setMode] = useState<\"replace\" | \"mix\">(\"replace\")\n  const [frequency, setFrequency] = useState(440)\n  const [levelDb, setLevelDb] = useState(-12)\n  const [durationMs, setDurationMs] = useState(500)\n\n  const statusByte = 0x80 + (status & 0x7f)\n\n  // The C4 preset holds the note for 500 ms and then releases it, so a\n  // developer gets a note *event pair* rather than a stuck note they then have\n  // to panic away. The timer is cleared on unmount for the same reason.\n  const noteTimer = useRef<number | null>(null)\n  useEffect(\n    () => () => {\n      if (noteTimer.current !== null && typeof window !== \"undefined\")\n        window.clearTimeout(noteTimer.current)\n    },\n    []\n  )\n\n  const firePreset = useCallback(\n    (preset: (typeof STIMULUS_PRESETS)[number]) => {\n      session.stimulate(preset.build())\n      if (preset.id !== \"note\" || typeof window === \"undefined\") return\n      if (noteTimer.current !== null) window.clearTimeout(noteTimer.current)\n      noteTimer.current = window.setTimeout(() => {\n        session.stimulate({\n          kind: \"injectMidi\",\n          events: [{ offset: 0, data: [0x80, 60, 0] }],\n        })\n        noteTimer.current = null\n      }, 500)\n    },\n    [session]\n  )\n\n  return (\n    <>\n      <Section title=\"One click\">\n        <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\" }}>\n          {STIMULUS_PRESETS.map((preset) => (\n            <Action\n              key={preset.id}\n              label={preset.label}\n              description={preset.title}\n              onClick={() => firePreset(preset)}\n              disabledReason={commandUnavailableReason(preset.command, commands)}\n            />\n          ))}\n        </div>\n      </Section>\n\n      <Section title=\"Transport\">\n        <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\" }}>\n          {(\n            [\n              [\"Play\", { kind: \"transport\", action: \"play\" }],\n              [\"Stop\", { kind: \"transport\", action: \"stop\" }],\n              [\"Locate 0\", { kind: \"transport\", action: \"locate\", ppq: 0 }],\n            ] as const\n          ).map(([label, stimulus]) => (\n            <Action\n              key={label}\n              label={label}\n              onClick={() => session.stimulate(stimulus)}\n              disabledReason={transportReason}\n            />\n          ))}\n        </div>\n      </Section>\n\n      <Section title=\"Notes\">\n        <PianoKeyboard\n          startNote={48}\n          octaves={2}\n          height={60}\n          onNoteOn={(note, velocity) =>\n            session.stimulate({\n              kind: \"injectMidi\",\n              events: [\n                {\n                  offset: 0,\n                  data: [0x90, note, Math.max(1, Math.round(velocity * 127))],\n                },\n              ],\n            })\n          }\n          onNoteOff={(note) =>\n            session.stimulate({\n              kind: \"injectMidi\",\n              events: [{ offset: 0, data: [0x80, note, 0] }],\n            })\n          }\n        />\n        {injectReason ? (\n          <p style={{ color: token.textMuted, fontSize: 11, marginTop: 6 }}>{injectReason}</p>\n        ) : null}\n      </Section>\n\n      <Section title=\"Raw MIDI\">\n        <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\", alignItems: \"center\" }}>\n          <label style={{ fontSize: 11, color: token.textMuted }}>\n            status 0x\n            <input\n              style={{ ...inputStyle, width: \"4rem\", marginLeft: 4 }}\n              value={statusByte.toString(16).toUpperCase()}\n              onChange={(event) => {\n                const parsed = Number.parseInt(event.target.value, 16)\n                if (Number.isFinite(parsed)) setStatus(parsed - 0x80)\n              }}\n            />\n          </label>\n          <input\n            style={{ ...inputStyle, width: \"4rem\" }}\n            type=\"number\"\n            min={0}\n            max={127}\n            value={data1}\n            onChange={(event) => setData1(Number(event.target.value))}\n            aria-label=\"Data byte 1\"\n          />\n          <input\n            style={{ ...inputStyle, width: \"4rem\" }}\n            type=\"number\"\n            min={0}\n            max={127}\n            value={data2}\n            onChange={(event) => setData2(Number(event.target.value))}\n            aria-label=\"Data byte 2\"\n          />\n          <Action\n            label=\"Send\"\n            onClick={() =>\n              session.stimulate({\n                kind: \"injectMidi\",\n                events: [\n                  {\n                    offset: 0,\n                    data: [statusByte & 0xff, data1 & 0x7f, data2 & 0x7f],\n                  },\n                ],\n              })\n            }\n            disabledReason={injectReason}\n          />\n        </div>\n        <p style={{ color: token.textMuted, fontSize: 11, marginTop: 6 }}>\n          Decoded: {decodeMidiMessage([statusByte, data1, data2]).description}\n        </p>\n        <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\", marginTop: 6 }}>\n          {(\n            [\n              [\"Clock\", 0xf8],\n              [\"Start\", 0xfa],\n              [\"Continue\", 0xfb],\n              [\"Stop\", 0xfc],\n            ] as const\n          ).map(([label, byte]) => (\n            <Action\n              key={label}\n              label={label}\n              onClick={() =>\n                session.stimulate({\n                  kind: \"injectMidi\",\n                  events: [{ offset: 0, data: [byte, 0, 0] }],\n                })\n              }\n              disabledReason={injectReason}\n            />\n          ))}\n        </div>\n      </Section>\n\n      <Section title=\"Test signal\">\n        <div style={{ display: \"grid\", gap: 6 }}>\n          <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\" }}>\n            <select\n              style={inputStyle}\n              value={signal}\n              onChange={(event) => setSignal(event.target.value as DiagnosticTestSignal)}\n              aria-label=\"Test signal\"\n            >\n              {TEST_SIGNALS.map((entry) => (\n                <option key={entry} value={entry}>\n                  {entry}\n                </option>\n              ))}\n            </select>\n            <select\n              style={inputStyle}\n              value={target}\n              onChange={(event) =>\n                setTarget(event.target.value as \"input\" | \"output\" | \"sidechain\")\n              }\n              aria-label=\"Target bus\"\n            >\n              <option value=\"input\">input</option>\n              <option value=\"output\">output</option>\n              <option value=\"sidechain\">sidechain</option>\n            </select>\n            <select\n              style={inputStyle}\n              value={mode}\n              onChange={(event) => setMode(event.target.value as \"replace\" | \"mix\")}\n              aria-label=\"Mix mode\"\n            >\n              <option value=\"replace\">replace</option>\n              <option value=\"mix\">mix</option>\n            </select>\n          </div>\n          <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\" }}>\n            <label style={{ fontSize: 11, color: token.textMuted }}>\n              Hz\n              <input\n                style={{ ...inputStyle, width: \"5rem\", marginLeft: 4 }}\n                type=\"number\"\n                value={frequency}\n                onChange={(event) => setFrequency(Number(event.target.value))}\n              />\n            </label>\n            <label style={{ fontSize: 11, color: token.textMuted }}>\n              dB\n              <input\n                style={{ ...inputStyle, width: \"5rem\", marginLeft: 4 }}\n                type=\"number\"\n                value={levelDb}\n                onChange={(event) => setLevelDb(Number(event.target.value))}\n              />\n            </label>\n            <label style={{ fontSize: 11, color: token.textMuted }}>\n              ms\n              <input\n                style={{ ...inputStyle, width: \"5rem\", marginLeft: 4 }}\n                type=\"number\"\n                value={durationMs}\n                onChange={(event) => setDurationMs(Number(event.target.value))}\n              />\n            </label>\n            <Action\n              label=\"Fire\"\n              onClick={() =>\n                session.stimulate({\n                  kind: \"testSignal\",\n                  signal,\n                  target,\n                  mode,\n                  frequencyHz: frequency,\n                  levelDb,\n                  durationMs,\n                })\n              }\n              disabledReason={signalReason}\n            />\n          </div>\n        </div>\n      </Section>\n\n      <Section title=\"Panic\">\n        <div style={{ display: \"flex\", gap: 6, flexWrap: \"wrap\" }}>\n          <Action\n            label=\"All notes off\"\n            onClick={() => session.stimulate({ kind: \"panic\" })}\n            disabledReason={panicReason}\n          />\n          <Action\n            label=\"Reset counters\"\n            onClick={() => session.stimulate({ kind: \"resetCounters\" })}\n            disabledReason={commandUnavailableReason(\"resetCounters\", commands)}\n          />\n        </div>\n      </Section>\n    </>\n  )\n}\n\nexport const StimulusTab = memo(StimulusTabImpl)\n\n/**\n * Clipboard write with a textarea fallback, SSR-safe.\n *\n * `navigator.clipboard` is unavailable on insecure origins and inside some\n * plugin webviews, which is exactly where this panel runs — so the fallback is\n * the common path rather than a nicety. Resolves false when neither works, so\n * the caller can avoid claiming success it did not have.\n */\nexport async function writeClipboard(text: string): Promise<boolean> {\n  if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n    try {\n      await navigator.clipboard.writeText(text)\n      return true\n    } catch {\n      // Fall through to the textarea path.\n    }\n  }\n  if (typeof document === \"undefined\") return false\n  try {\n    const area = document.createElement(\"textarea\")\n    area.value = text\n    area.setAttribute(\"readonly\", \"\")\n    area.style.position = \"fixed\"\n    area.style.opacity = \"0\"\n    area.style.pointerEvents = \"none\"\n    document.body.appendChild(area)\n    area.select()\n    const ok = document.execCommand(\"copy\")\n    document.body.removeChild(area)\n    return ok\n  } catch {\n    return false\n  }\n}\n",
      "type": "registry:component",
      "target": "@ui/diagnostic-tabs-live.tsx"
    }
  ]
}
