{"version":3,"file":"index.cjs","names":["LitElement","nothing","tailwindStyles","inspectorLogoIconUrl","inspectorLogoUrl","loadInspectorState","isValidDockMode","isValidAnchor","isValidPosition","isValidSize","constrainToViewport","clampSizeToViewport","icons","CopilotKitCoreRuntimeConnectionStatus"],"sources":["../src/index.ts"],"sourcesContent":["import { LitElement, css, html, nothing, unsafeCSS } from \"lit\";\nimport { styleMap } from \"lit/directives/style-map.js\";\nimport tailwindStyles from \"./styles/generated.css\";\nimport inspectorLogoUrl from \"./assets/inspector-logo.svg\";\nimport inspectorLogoIconUrl from \"./assets/inspector-logo-icon.svg\";\nimport { unsafeHTML } from \"lit/directives/unsafe-html.js\";\nimport { marked } from \"marked\";\nimport { icons } from \"lucide\";\nimport {\n  CopilotKitCore,\n  CopilotKitCoreRuntimeConnectionStatus,\n  type CopilotKitCoreSubscriber,\n  type CopilotKitCoreErrorCode,\n} from \"@copilotkitnext/core\";\nimport type { AbstractAgent, AgentSubscriber } from \"@ag-ui/client\";\nimport type {\n  Anchor,\n  ContextKey,\n  ContextState,\n  DockMode,\n  Position,\n  Size,\n} from \"./lib/types\";\nimport {\n  applyAnchorPosition as applyAnchorPositionHelper,\n  centerContext as centerContextHelper,\n  constrainToViewport,\n  keepPositionWithinViewport,\n  updateAnchorFromPosition as updateAnchorFromPositionHelper,\n  updateSizeFromElement,\n  clampSize as clampSizeToViewport,\n} from \"./lib/context-helpers\";\nimport {\n  loadInspectorState,\n  saveInspectorState,\n  type PersistedState,\n  isValidAnchor,\n  isValidPosition,\n  isValidSize,\n  isValidDockMode,\n} from \"./lib/persistence\";\n\nexport const WEB_INSPECTOR_TAG = \"cpk-web-inspector\" as const;\n\ntype LucideIconName = keyof typeof icons;\n\ntype MenuKey = \"ag-ui-events\" | \"agents\" | \"frontend-tools\" | \"agent-context\";\n\ntype MenuItem = {\n  key: MenuKey;\n  label: string;\n  icon: LucideIconName;\n};\n\nconst EDGE_MARGIN = 16;\nconst DRAG_THRESHOLD = 6;\nconst MIN_WINDOW_WIDTH = 600;\nconst MIN_WINDOW_WIDTH_DOCKED_LEFT = 420;\nconst MIN_WINDOW_HEIGHT = 200;\nconst INSPECTOR_STORAGE_KEY = \"cpk:inspector:state\";\nconst ANNOUNCEMENT_STORAGE_KEY = \"cpk:inspector:announcements\";\nconst ANNOUNCEMENT_URL = \"https://cdn.copilotkit.ai/announcements.json\";\nconst DEFAULT_BUTTON_SIZE: Size = { width: 48, height: 48 };\nconst DEFAULT_WINDOW_SIZE: Size = { width: 840, height: 560 };\nconst DOCKED_LEFT_WIDTH = 500; // Sensible width for left dock with collapsed sidebar\nconst MAX_AGENT_EVENTS = 200;\nconst MAX_TOTAL_EVENTS = 500;\n\ntype InspectorAgentEventType =\n  | \"RUN_STARTED\"\n  | \"RUN_FINISHED\"\n  | \"RUN_ERROR\"\n  | \"TEXT_MESSAGE_START\"\n  | \"TEXT_MESSAGE_CONTENT\"\n  | \"TEXT_MESSAGE_END\"\n  | \"TOOL_CALL_START\"\n  | \"TOOL_CALL_ARGS\"\n  | \"TOOL_CALL_END\"\n  | \"TOOL_CALL_RESULT\"\n  | \"STATE_SNAPSHOT\"\n  | \"STATE_DELTA\"\n  | \"MESSAGES_SNAPSHOT\"\n  | \"RAW_EVENT\"\n  | \"CUSTOM_EVENT\"\n  | \"REASONING_START\"\n  | \"REASONING_MESSAGE_START\"\n  | \"REASONING_MESSAGE_CONTENT\"\n  | \"REASONING_MESSAGE_END\"\n  | \"REASONING_END\"\n  | \"REASONING_ENCRYPTED_VALUE\";\n\nconst AGENT_EVENT_TYPES: readonly InspectorAgentEventType[] = [\n  \"RUN_STARTED\",\n  \"RUN_FINISHED\",\n  \"RUN_ERROR\",\n  \"TEXT_MESSAGE_START\",\n  \"TEXT_MESSAGE_CONTENT\",\n  \"TEXT_MESSAGE_END\",\n  \"TOOL_CALL_START\",\n  \"TOOL_CALL_ARGS\",\n  \"TOOL_CALL_END\",\n  \"TOOL_CALL_RESULT\",\n  \"STATE_SNAPSHOT\",\n  \"STATE_DELTA\",\n  \"MESSAGES_SNAPSHOT\",\n  \"RAW_EVENT\",\n  \"CUSTOM_EVENT\",\n  \"REASONING_START\",\n  \"REASONING_MESSAGE_START\",\n  \"REASONING_MESSAGE_CONTENT\",\n  \"REASONING_MESSAGE_END\",\n  \"REASONING_END\",\n  \"REASONING_ENCRYPTED_VALUE\",\n] as const;\n\ntype SanitizedValue =\n  | string\n  | number\n  | boolean\n  | null\n  | SanitizedValue[]\n  | { [key: string]: SanitizedValue };\n\ntype InspectorToolCall = {\n  id?: string;\n  function?: {\n    name?: string;\n    arguments?: SanitizedValue | string;\n  };\n  toolName?: string;\n  status?: string;\n};\n\ntype InspectorMessage = {\n  id?: string;\n  role: string;\n  contentText: string;\n  contentRaw?: SanitizedValue;\n  toolCalls: InspectorToolCall[];\n};\n\ntype InspectorToolDefinition = {\n  agentId: string;\n  name: string;\n  description?: string;\n  parameters?: unknown;\n  type: \"handler\" | \"renderer\";\n};\n\ntype InspectorEvent = {\n  id: string;\n  agentId: string;\n  type: InspectorAgentEventType;\n  timestamp: number;\n  payload: SanitizedValue;\n};\n\nexport class WebInspectorElement extends LitElement {\n  static properties = {\n    core: { attribute: false },\n    autoAttachCore: { type: Boolean, attribute: \"auto-attach-core\" },\n  } as const;\n\n  private _core: CopilotKitCore | null = null;\n  private coreSubscriber: CopilotKitCoreSubscriber | null = null;\n  private coreUnsubscribe: (() => void) | null = null;\n  private runtimeStatus: CopilotKitCoreRuntimeConnectionStatus | null = null;\n  private coreProperties: Readonly<Record<string, unknown>> = {};\n  private lastCoreError: {\n    code: CopilotKitCoreErrorCode;\n    message: string;\n  } | null = null;\n  private agentSubscriptions: Map<string, () => void> = new Map();\n  private agentEvents: Map<string, InspectorEvent[]> = new Map();\n  private agentMessages: Map<string, InspectorMessage[]> = new Map();\n  private agentStates: Map<string, SanitizedValue> = new Map();\n  private flattenedEvents: InspectorEvent[] = [];\n  private eventCounter = 0;\n  private contextStore: Record<\n    string,\n    { description?: string; value: unknown }\n  > = {};\n\n  private pointerId: number | null = null;\n  private dragStart: Position | null = null;\n  private dragOffset: Position = { x: 0, y: 0 };\n  private isDragging = false;\n  private pointerContext: ContextKey | null = null;\n  private isOpen = false;\n  private draggedDuringInteraction = false;\n  private ignoreNextButtonClick = false;\n  private selectedMenu: MenuKey = \"ag-ui-events\";\n  private contextMenuOpen = false;\n  private dockMode: DockMode = \"floating\";\n  private previousBodyMargins: { left: string; bottom: string } | null = null;\n  private transitionTimeoutId: ReturnType<typeof setTimeout> | null = null;\n  private pendingSelectedContext: string | null = null;\n  private autoAttachCore = true;\n  private attemptedAutoAttach = false;\n  private cachedTools: InspectorToolDefinition[] = [];\n  private toolSignature = \"\";\n  private eventFilterText = \"\";\n  private eventTypeFilter: InspectorAgentEventType | \"all\" = \"all\";\n\n  private announcementMarkdown: string | null = null;\n  private announcementHtml: string | null = null;\n  private announcementTimestamp: string | null = null;\n  private announcementPreviewText: string | null = null;\n  private hasUnseenAnnouncement = false;\n  private announcementLoaded = false;\n  private announcementLoadError: unknown = null;\n  private announcementPromise: Promise<void> | null = null;\n  private showAnnouncementPreview = true;\n\n  get core(): CopilotKitCore | null {\n    return this._core;\n  }\n\n  set core(value: CopilotKitCore | null) {\n    const oldValue = this._core;\n    if (oldValue === value) {\n      return;\n    }\n\n    this.detachFromCore();\n\n    this._core = value ?? null;\n    this.requestUpdate(\"core\", oldValue);\n\n    if (this._core) {\n      this.attachToCore(this._core);\n    }\n  }\n\n  private readonly contextState: Record<ContextKey, ContextState> = {\n    button: {\n      position: { x: EDGE_MARGIN, y: EDGE_MARGIN },\n      size: { ...DEFAULT_BUTTON_SIZE },\n      anchor: { horizontal: \"right\", vertical: \"top\" },\n      anchorOffset: { x: EDGE_MARGIN, y: EDGE_MARGIN },\n    },\n    window: {\n      position: { x: EDGE_MARGIN, y: EDGE_MARGIN },\n      size: { ...DEFAULT_WINDOW_SIZE },\n      anchor: { horizontal: \"right\", vertical: \"top\" },\n      anchorOffset: { x: EDGE_MARGIN, y: EDGE_MARGIN },\n    },\n  };\n\n  private hasCustomPosition: Record<ContextKey, boolean> = {\n    button: false,\n    window: false,\n  };\n\n  private resizePointerId: number | null = null;\n  private resizeStart: Position | null = null;\n  private resizeInitialSize: { width: number; height: number } | null = null;\n  private isResizing = false;\n\n  private readonly menuItems: MenuItem[] = [\n    { key: \"ag-ui-events\", label: \"AG-UI Events\", icon: \"Zap\" },\n    { key: \"agents\", label: \"Agent\", icon: \"Bot\" },\n    { key: \"frontend-tools\", label: \"Frontend Tools\", icon: \"Hammer\" },\n    { key: \"agent-context\", label: \"Context\", icon: \"FileText\" },\n  ];\n\n  private attachToCore(core: CopilotKitCore): void {\n    this.runtimeStatus = core.runtimeConnectionStatus;\n    this.coreProperties = core.properties;\n    this.lastCoreError = null;\n\n    this.coreSubscriber = {\n      onRuntimeConnectionStatusChanged: ({ status }) => {\n        this.runtimeStatus = status;\n        this.requestUpdate();\n      },\n      onPropertiesChanged: ({ properties }) => {\n        this.coreProperties = properties;\n        this.requestUpdate();\n      },\n      onError: ({ code, error }) => {\n        this.lastCoreError = { code, message: error.message };\n        this.requestUpdate();\n      },\n      onAgentsChanged: ({ agents }) => {\n        this.processAgentsChanged(agents);\n      },\n      onContextChanged: ({ context }) => {\n        this.contextStore = this.normalizeContextStore(context);\n        this.requestUpdate();\n      },\n    } satisfies CopilotKitCoreSubscriber;\n\n    this.coreUnsubscribe = core.subscribe(this.coreSubscriber).unsubscribe;\n    this.processAgentsChanged(core.agents);\n\n    // Initialize context from core\n    if (core.context) {\n      this.contextStore = this.normalizeContextStore(core.context);\n    }\n  }\n\n  private detachFromCore(): void {\n    if (this.coreUnsubscribe) {\n      this.coreUnsubscribe();\n      this.coreUnsubscribe = null;\n    }\n    this.coreSubscriber = null;\n    this.runtimeStatus = null;\n    this.lastCoreError = null;\n    this.coreProperties = {};\n    this.cachedTools = [];\n    this.toolSignature = \"\";\n    this.teardownAgentSubscriptions();\n  }\n\n  private teardownAgentSubscriptions(): void {\n    for (const unsubscribe of this.agentSubscriptions.values()) {\n      unsubscribe();\n    }\n    this.agentSubscriptions.clear();\n    this.agentEvents.clear();\n    this.agentMessages.clear();\n    this.agentStates.clear();\n    this.flattenedEvents = [];\n    this.eventCounter = 0;\n  }\n\n  private processAgentsChanged(\n    agents: Readonly<Record<string, AbstractAgent>>,\n  ): void {\n    const seenAgentIds = new Set<string>();\n\n    for (const agent of Object.values(agents)) {\n      if (!agent?.agentId) {\n        continue;\n      }\n      seenAgentIds.add(agent.agentId);\n      this.subscribeToAgent(agent);\n    }\n\n    for (const agentId of Array.from(this.agentSubscriptions.keys())) {\n      if (!seenAgentIds.has(agentId)) {\n        this.unsubscribeFromAgent(agentId);\n        this.agentEvents.delete(agentId);\n        this.agentMessages.delete(agentId);\n        this.agentStates.delete(agentId);\n      }\n    }\n\n    this.updateContextOptions(seenAgentIds);\n    this.refreshToolsSnapshot();\n    this.requestUpdate();\n  }\n\n  private refreshToolsSnapshot(): void {\n    if (!this._core) {\n      if (this.cachedTools.length > 0) {\n        this.cachedTools = [];\n        this.toolSignature = \"\";\n        this.requestUpdate();\n      }\n      return;\n    }\n\n    const tools = this.extractToolsFromAgents();\n    const signature = JSON.stringify(\n      tools.map((tool) => ({\n        agentId: tool.agentId,\n        name: tool.name,\n        type: tool.type,\n        hasDescription: Boolean(tool.description),\n        hasParameters: Boolean(tool.parameters),\n      })),\n    );\n\n    if (signature !== this.toolSignature) {\n      this.toolSignature = signature;\n      this.cachedTools = tools;\n      this.requestUpdate();\n    }\n  }\n\n  private tryAutoAttachCore(): void {\n    if (\n      this.attemptedAutoAttach ||\n      this._core ||\n      !this.autoAttachCore ||\n      typeof window === \"undefined\"\n    ) {\n      return;\n    }\n\n    this.attemptedAutoAttach = true;\n\n    const globalWindow = window as unknown as Record<string, unknown>;\n    const globalCandidates: Array<unknown> = [\n      // Common app-level globals used during development\n      globalWindow.__COPILOTKIT_CORE__,\n      (globalWindow.copilotkit as { core?: unknown } | undefined)?.core,\n      globalWindow.copilotkitCore,\n    ];\n\n    const foundCore = globalCandidates.find(\n      (candidate): candidate is CopilotKitCore =>\n        !!candidate && typeof candidate === \"object\",\n    );\n\n    if (foundCore) {\n      this.core = foundCore;\n    }\n  }\n\n  private subscribeToAgent(agent: AbstractAgent): void {\n    if (!agent.agentId) {\n      return;\n    }\n\n    const agentId = agent.agentId;\n\n    this.unsubscribeFromAgent(agentId);\n\n    const subscriber: AgentSubscriber = {\n      onRunStartedEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"RUN_STARTED\", event);\n      },\n      onRunFinishedEvent: ({ event, result }) => {\n        this.recordAgentEvent(agentId, \"RUN_FINISHED\", { event, result });\n      },\n      onRunErrorEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"RUN_ERROR\", event);\n      },\n      onTextMessageStartEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"TEXT_MESSAGE_START\", event);\n      },\n      onTextMessageContentEvent: ({ event, textMessageBuffer }) => {\n        this.recordAgentEvent(agentId, \"TEXT_MESSAGE_CONTENT\", {\n          event,\n          textMessageBuffer,\n        });\n      },\n      onTextMessageEndEvent: ({ event, textMessageBuffer }) => {\n        this.recordAgentEvent(agentId, \"TEXT_MESSAGE_END\", {\n          event,\n          textMessageBuffer,\n        });\n      },\n      onToolCallStartEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"TOOL_CALL_START\", event);\n      },\n      onToolCallArgsEvent: ({\n        event,\n        toolCallBuffer,\n        toolCallName,\n        partialToolCallArgs,\n      }) => {\n        this.recordAgentEvent(agentId, \"TOOL_CALL_ARGS\", {\n          event,\n          toolCallBuffer,\n          toolCallName,\n          partialToolCallArgs,\n        });\n      },\n      onToolCallEndEvent: ({ event, toolCallArgs, toolCallName }) => {\n        this.recordAgentEvent(agentId, \"TOOL_CALL_END\", {\n          event,\n          toolCallArgs,\n          toolCallName,\n        });\n      },\n      onToolCallResultEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"TOOL_CALL_RESULT\", event);\n      },\n      onStateSnapshotEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"STATE_SNAPSHOT\", event);\n        this.syncAgentState(agent);\n      },\n      onStateDeltaEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"STATE_DELTA\", event);\n        this.syncAgentState(agent);\n      },\n      onMessagesSnapshotEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"MESSAGES_SNAPSHOT\", event);\n        this.syncAgentMessages(agent);\n      },\n      onMessagesChanged: () => {\n        this.syncAgentMessages(agent);\n      },\n      onRawEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"RAW_EVENT\", event);\n      },\n      onCustomEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"CUSTOM_EVENT\", event);\n      },\n      onReasoningStartEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"REASONING_START\", event);\n      },\n      onReasoningMessageStartEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"REASONING_MESSAGE_START\", event);\n      },\n      onReasoningMessageContentEvent: ({ event, reasoningMessageBuffer }) => {\n        this.recordAgentEvent(agentId, \"REASONING_MESSAGE_CONTENT\", {\n          event,\n          reasoningMessageBuffer,\n        });\n      },\n      onReasoningMessageEndEvent: ({ event, reasoningMessageBuffer }) => {\n        this.recordAgentEvent(agentId, \"REASONING_MESSAGE_END\", {\n          event,\n          reasoningMessageBuffer,\n        });\n      },\n      onReasoningEndEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"REASONING_END\", event);\n      },\n      onReasoningEncryptedValueEvent: ({ event }) => {\n        this.recordAgentEvent(agentId, \"REASONING_ENCRYPTED_VALUE\", event);\n      },\n    };\n\n    const { unsubscribe } = agent.subscribe(subscriber);\n    this.agentSubscriptions.set(agentId, unsubscribe);\n    this.syncAgentMessages(agent);\n    this.syncAgentState(agent);\n\n    if (!this.agentEvents.has(agentId)) {\n      this.agentEvents.set(agentId, []);\n    }\n  }\n\n  private unsubscribeFromAgent(agentId: string): void {\n    const unsubscribe = this.agentSubscriptions.get(agentId);\n    if (unsubscribe) {\n      unsubscribe();\n      this.agentSubscriptions.delete(agentId);\n    }\n  }\n\n  private recordAgentEvent(\n    agentId: string,\n    type: InspectorAgentEventType,\n    payload: unknown,\n  ): void {\n    const eventId = `${agentId}:${++this.eventCounter}`;\n    const normalizedPayload = this.normalizeEventPayload(type, payload);\n    const event: InspectorEvent = {\n      id: eventId,\n      agentId,\n      type,\n      timestamp: Date.now(),\n      payload: normalizedPayload,\n    };\n\n    const currentAgentEvents = this.agentEvents.get(agentId) ?? [];\n    const nextAgentEvents = [event, ...currentAgentEvents].slice(\n      0,\n      MAX_AGENT_EVENTS,\n    );\n    this.agentEvents.set(agentId, nextAgentEvents);\n\n    this.flattenedEvents = [event, ...this.flattenedEvents].slice(\n      0,\n      MAX_TOTAL_EVENTS,\n    );\n    this.refreshToolsSnapshot();\n    this.requestUpdate();\n  }\n\n  private syncAgentMessages(agent: AbstractAgent): void {\n    if (!agent?.agentId) {\n      return;\n    }\n\n    const messages = this.normalizeAgentMessages(\n      (agent as { messages?: unknown }).messages,\n    );\n    if (messages) {\n      this.agentMessages.set(agent.agentId, messages);\n    } else {\n      this.agentMessages.delete(agent.agentId);\n    }\n\n    this.requestUpdate();\n  }\n\n  private syncAgentState(agent: AbstractAgent): void {\n    if (!agent?.agentId) {\n      return;\n    }\n\n    const state = (agent as { state?: unknown }).state;\n\n    if (state === undefined || state === null) {\n      this.agentStates.delete(agent.agentId);\n    } else {\n      this.agentStates.set(agent.agentId, this.sanitizeForLogging(state));\n    }\n\n    this.requestUpdate();\n  }\n\n  private updateContextOptions(agentIds: Set<string>): void {\n    const nextOptions: Array<{ key: string; label: string }> = [\n      { key: \"all-agents\", label: \"All Agents\" },\n      ...Array.from(agentIds)\n        .sort((a, b) => a.localeCompare(b))\n        .map((id) => ({ key: id, label: id })),\n    ];\n\n    const optionsChanged =\n      this.contextOptions.length !== nextOptions.length ||\n      this.contextOptions.some(\n        (option, index) => option.key !== nextOptions[index]?.key,\n      );\n\n    if (optionsChanged) {\n      this.contextOptions = nextOptions;\n    }\n\n    const pendingContext = this.pendingSelectedContext;\n    if (pendingContext) {\n      const isPendingAvailable =\n        pendingContext === \"all-agents\" || agentIds.has(pendingContext);\n      if (isPendingAvailable) {\n        if (this.selectedContext !== pendingContext) {\n          this.selectedContext = pendingContext;\n          this.expandedRows.clear();\n        }\n        this.pendingSelectedContext = null;\n      } else if (agentIds.size > 0) {\n        // Agents are loaded but the pending selection no longer exists\n        this.pendingSelectedContext = null;\n      }\n    }\n\n    const hasSelectedContext = nextOptions.some(\n      (option) => option.key === this.selectedContext,\n    );\n\n    if (!hasSelectedContext && this.pendingSelectedContext === null) {\n      // Auto-select \"default\" agent if it exists, otherwise first agent, otherwise \"all-agents\"\n      let nextSelected: string = \"all-agents\";\n\n      if (agentIds.has(\"default\")) {\n        nextSelected = \"default\";\n      } else if (agentIds.size > 0) {\n        nextSelected = Array.from(agentIds).sort((a, b) =>\n          a.localeCompare(b),\n        )[0]!;\n      }\n\n      if (this.selectedContext !== nextSelected) {\n        this.selectedContext = nextSelected;\n        this.expandedRows.clear();\n        this.persistState();\n      }\n    }\n  }\n\n  private getEventsForSelectedContext(): InspectorEvent[] {\n    if (this.selectedContext === \"all-agents\") {\n      return this.flattenedEvents;\n    }\n\n    return this.agentEvents.get(this.selectedContext) ?? [];\n  }\n\n  private filterEvents(events: InspectorEvent[]): InspectorEvent[] {\n    const query = this.eventFilterText.trim().toLowerCase();\n\n    return events.filter((event) => {\n      if (\n        this.eventTypeFilter !== \"all\" &&\n        event.type !== this.eventTypeFilter\n      ) {\n        return false;\n      }\n\n      if (!query) {\n        return true;\n      }\n\n      const payloadText = this.stringifyPayload(\n        event.payload,\n        false,\n      ).toLowerCase();\n      return (\n        event.type.toLowerCase().includes(query) ||\n        event.agentId.toLowerCase().includes(query) ||\n        payloadText.includes(query)\n      );\n    });\n  }\n\n  private getLatestStateForAgent(agentId: string): SanitizedValue | null {\n    if (this.agentStates.has(agentId)) {\n      const value = this.agentStates.get(agentId);\n      return value === undefined ? null : value;\n    }\n\n    const events = this.agentEvents.get(agentId) ?? [];\n    const stateEvent = events.find((e) => e.type === \"STATE_SNAPSHOT\");\n    if (!stateEvent) {\n      return null;\n    }\n    return stateEvent.payload;\n  }\n\n  private getLatestMessagesForAgent(\n    agentId: string,\n  ): InspectorMessage[] | null {\n    const messages = this.agentMessages.get(agentId);\n    return messages ?? null;\n  }\n\n  private getAgentStatus(agentId: string): \"running\" | \"idle\" | \"error\" {\n    const events = this.agentEvents.get(agentId) ?? [];\n    if (events.length === 0) {\n      return \"idle\";\n    }\n\n    // Check most recent run-related event\n    const runEvent = events.find(\n      (e) =>\n        e.type === \"RUN_STARTED\" ||\n        e.type === \"RUN_FINISHED\" ||\n        e.type === \"RUN_ERROR\",\n    );\n\n    if (!runEvent) {\n      return \"idle\";\n    }\n\n    if (runEvent.type === \"RUN_ERROR\") {\n      return \"error\";\n    }\n\n    if (runEvent.type === \"RUN_STARTED\") {\n      // Check if there's a RUN_FINISHED after this\n      const finishedAfter = events.find(\n        (e) => e.type === \"RUN_FINISHED\" && e.timestamp > runEvent.timestamp,\n      );\n      return finishedAfter ? \"idle\" : \"running\";\n    }\n\n    return \"idle\";\n  }\n\n  private getAgentStats(agentId: string): {\n    totalEvents: number;\n    lastActivity: number | null;\n    messages: number;\n    toolCalls: number;\n    errors: number;\n  } {\n    const events = this.agentEvents.get(agentId) ?? [];\n\n    const messages = this.agentMessages.get(agentId);\n\n    const toolCallCount = messages\n      ? messages.reduce(\n          (count, message) => count + (message.toolCalls?.length ?? 0),\n          0,\n        )\n      : events.filter((e) => e.type === \"TOOL_CALL_END\").length;\n\n    const messageCount = messages?.length ?? 0;\n\n    return {\n      totalEvents: events.length,\n      lastActivity: events[0]?.timestamp ?? null,\n      messages: messageCount,\n      toolCalls: toolCallCount,\n      errors: events.filter((e) => e.type === \"RUN_ERROR\").length,\n    };\n  }\n\n  private renderToolCallDetails(toolCalls: InspectorToolCall[]) {\n    if (!Array.isArray(toolCalls) || toolCalls.length === 0) {\n      return nothing;\n    }\n\n    return html`\n      <div class=\"mt-2 space-y-2\">\n        ${toolCalls.map((call, index) => {\n          const functionName =\n            call.function?.name ?? call.toolName ?? \"Unknown function\";\n          const callId =\n            typeof call?.id === \"string\" ? call.id : `tool-call-${index + 1}`;\n          const argsString = this.formatToolCallArguments(\n            call.function?.arguments,\n          );\n          return html`\n            <div\n              class=\"rounded-md border border-gray-200 bg-gray-50 p-3 text-xs text-gray-700\"\n            >\n              <div\n                class=\"flex flex-wrap items-center justify-between gap-1 font-medium text-gray-900\"\n              >\n                <span>${functionName}</span>\n                <span class=\"text-[10px] text-gray-500\">ID: ${callId}</span>\n              </div>\n              ${argsString\n                ? html`<pre\n                    class=\"mt-2 overflow-auto rounded bg-white p-2 text-[11px] leading-relaxed text-gray-800\"\n                  >\n${argsString}</pre\n                  >`\n                : nothing}\n            </div>\n          `;\n        })}\n      </div>\n    `;\n  }\n\n  private formatToolCallArguments(args: unknown): string | null {\n    if (args === undefined || args === null || args === \"\") {\n      return null;\n    }\n\n    if (typeof args === \"string\") {\n      try {\n        const parsed = JSON.parse(args);\n        return JSON.stringify(parsed, null, 2);\n      } catch {\n        return args;\n      }\n    }\n\n    if (typeof args === \"object\") {\n      try {\n        return JSON.stringify(args, null, 2);\n      } catch {\n        return String(args);\n      }\n    }\n\n    return String(args);\n  }\n\n  private hasRenderableState(state: unknown): boolean {\n    if (state === null || state === undefined) {\n      return false;\n    }\n\n    if (Array.isArray(state)) {\n      return state.length > 0;\n    }\n\n    if (typeof state === \"object\") {\n      return Object.keys(state as Record<string, unknown>).length > 0;\n    }\n\n    if (typeof state === \"string\") {\n      const trimmed = state.trim();\n      return trimmed.length > 0 && trimmed !== \"{}\";\n    }\n\n    return true;\n  }\n\n  private formatStateForDisplay(state: unknown): string {\n    if (state === null || state === undefined) {\n      return \"\";\n    }\n\n    if (typeof state === \"string\") {\n      const trimmed = state.trim();\n      if (trimmed.length === 0) {\n        return \"\";\n      }\n      try {\n        const parsed = JSON.parse(trimmed);\n        return JSON.stringify(parsed, null, 2);\n      } catch {\n        return state;\n      }\n    }\n\n    if (typeof state === \"object\") {\n      try {\n        return JSON.stringify(state, null, 2);\n      } catch {\n        return String(state);\n      }\n    }\n\n    return String(state);\n  }\n\n  private getEventBadgeClasses(type: string): string {\n    const base =\n      \"font-mono text-[10px] font-medium inline-flex items-center rounded-sm px-1.5 py-0.5 border\";\n\n    if (type.startsWith(\"RUN_\")) {\n      return `${base} bg-blue-50 text-blue-700 border-blue-200`;\n    }\n\n    if (type.startsWith(\"TEXT_MESSAGE\")) {\n      return `${base} bg-emerald-50 text-emerald-700 border-emerald-200`;\n    }\n\n    if (type.startsWith(\"TOOL_CALL\")) {\n      return `${base} bg-amber-50 text-amber-700 border-amber-200`;\n    }\n\n    if (type.startsWith(\"REASONING\")) {\n      return `${base} bg-fuchsia-50 text-fuchsia-700 border-fuchsia-200`;\n    }\n\n    if (type.startsWith(\"STATE\")) {\n      return `${base} bg-violet-50 text-violet-700 border-violet-200`;\n    }\n\n    if (type.startsWith(\"MESSAGES\")) {\n      return `${base} bg-sky-50 text-sky-700 border-sky-200`;\n    }\n\n    if (type === \"RUN_ERROR\") {\n      return `${base} bg-rose-50 text-rose-700 border-rose-200`;\n    }\n\n    return `${base} bg-gray-100 text-gray-600 border-gray-200`;\n  }\n\n  private stringifyPayload(payload: unknown, pretty: boolean): string {\n    try {\n      if (payload === undefined) {\n        return pretty ? \"undefined\" : \"undefined\";\n      }\n      if (typeof payload === \"string\") {\n        return payload;\n      }\n      return JSON.stringify(payload, null, pretty ? 2 : 0) ?? \"\";\n    } catch (error) {\n      console.warn(\"Failed to stringify inspector payload\", error);\n      return String(payload);\n    }\n  }\n\n  private extractEventFromPayload(payload: unknown): unknown {\n    // If payload is an object with an 'event' field, extract it\n    if (payload && typeof payload === \"object\" && \"event\" in payload) {\n      return (payload as Record<string, unknown>).event;\n    }\n    // Otherwise, assume the payload itself is the event\n    return payload;\n  }\n\n  private async copyToClipboard(text: string, eventId: string): Promise<void> {\n    try {\n      await navigator.clipboard.writeText(text);\n      this.copiedEvents.add(eventId);\n      this.requestUpdate();\n\n      // Clear the \"copied\" state after 2 seconds\n      setTimeout(() => {\n        this.copiedEvents.delete(eventId);\n        this.requestUpdate();\n      }, 2000);\n    } catch (err) {\n      console.error(\"Failed to copy to clipboard:\", err);\n    }\n  }\n\n  static styles = [\n    unsafeCSS(tailwindStyles),\n    css`\n      :host {\n        position: fixed;\n        top: 0;\n        left: 0;\n        z-index: 2147483646;\n        display: block;\n        will-change: transform;\n      }\n\n      :host([data-transitioning=\"true\"]) {\n        transition: transform 300ms ease;\n      }\n\n      .console-button {\n        transition:\n          transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1),\n          opacity 160ms ease;\n      }\n\n      .console-button[data-dragging=\"true\"] {\n        transition: opacity 160ms ease;\n      }\n\n      .inspector-window[data-transitioning=\"true\"] {\n        transition:\n          width 300ms ease,\n          height 300ms ease;\n      }\n\n      .inspector-window[data-docked=\"true\"] {\n        border-radius: 0 !important;\n        box-shadow: none !important;\n      }\n\n      .resize-handle {\n        touch-action: none;\n        user-select: none;\n      }\n\n      .dock-resize-handle {\n        position: absolute;\n        top: 0;\n        right: 0;\n        width: 10px;\n        height: 100%;\n        cursor: ew-resize;\n        touch-action: none;\n        z-index: 50;\n        background: transparent;\n      }\n\n      .tooltip-target {\n        position: relative;\n      }\n\n      .tooltip-target::after {\n        content: attr(data-tooltip);\n        position: absolute;\n        top: calc(100% + 6px);\n        left: 50%;\n        transform: translateX(-50%) translateY(-4px);\n        white-space: nowrap;\n        background: rgba(17, 24, 39, 0.95);\n        color: white;\n        padding: 4px 8px;\n        border-radius: 6px;\n        font-size: 10px;\n        line-height: 1.2;\n        box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);\n        opacity: 0;\n        pointer-events: none;\n        transition:\n          opacity 120ms ease,\n          transform 120ms ease;\n        z-index: 4000;\n      }\n\n      .tooltip-target:hover::after {\n        opacity: 1;\n        transform: translateX(-50%) translateY(0);\n      }\n\n      .announcement-preview {\n        position: absolute;\n        top: 50%;\n        transform: translateY(-50%);\n        min-width: 300px;\n        max-width: 300px;\n        background: white;\n        color: #111827;\n        font-size: 13px;\n        line-height: 1.4;\n        border-radius: 12px;\n        box-shadow: 0 12px 28px rgba(15, 23, 42, 0.22);\n        padding: 10px 12px;\n        display: inline-flex;\n        align-items: flex-start;\n        gap: 8px;\n        z-index: 4500;\n        animation: fade-slide-in 160ms ease;\n        border: 1px solid rgba(148, 163, 184, 0.35);\n        white-space: normal;\n        word-break: break-word;\n        text-align: left;\n      }\n\n      .announcement-preview[data-side=\"left\"] {\n        right: 100%;\n        margin-right: 10px;\n      }\n\n      .announcement-preview[data-side=\"right\"] {\n        left: 100%;\n        margin-left: 10px;\n      }\n\n      .announcement-preview__arrow {\n        position: absolute;\n        width: 10px;\n        height: 10px;\n        background: white;\n        border: 1px solid rgba(148, 163, 184, 0.35);\n        transform: rotate(45deg);\n        top: 50%;\n        margin-top: -5px;\n        z-index: -1;\n      }\n\n      .announcement-preview[data-side=\"left\"] .announcement-preview__arrow {\n        right: -5px;\n        box-shadow: 6px -6px 10px rgba(15, 23, 42, 0.12);\n      }\n\n      .announcement-preview[data-side=\"right\"] .announcement-preview__arrow {\n        left: -5px;\n        box-shadow: -6px 6px 10px rgba(15, 23, 42, 0.12);\n      }\n\n      .announcement-dismiss {\n        color: #6b7280;\n        font-size: 12px;\n        padding: 2px 8px;\n        border-radius: 8px;\n        border: 1px solid rgba(148, 163, 184, 0.5);\n        background: rgba(248, 250, 252, 0.9);\n        transition:\n          background 120ms ease,\n          color 120ms ease;\n      }\n\n      .announcement-dismiss:hover {\n        background: rgba(241, 245, 249, 1);\n        color: #111827;\n      }\n\n      .announcement-content {\n        color: #111827;\n        font-size: 14px;\n        line-height: 1.6;\n      }\n\n      .announcement-content h1,\n      .announcement-content h2,\n      .announcement-content h3 {\n        font-weight: 700;\n        margin: 0.4rem 0 0.2rem;\n      }\n\n      .announcement-content h1 {\n        font-size: 1.1rem;\n      }\n\n      .announcement-content h2 {\n        font-size: 1rem;\n      }\n\n      .announcement-content h3 {\n        font-size: 0.95rem;\n      }\n\n      .announcement-content p {\n        margin: 0.25rem 0;\n      }\n\n      .announcement-content ul {\n        list-style: disc;\n        padding-left: 1.25rem;\n        margin: 0.3rem 0;\n      }\n\n      .announcement-content ol {\n        list-style: decimal;\n        padding-left: 1.25rem;\n        margin: 0.3rem 0;\n      }\n\n      .announcement-content a {\n        color: #0f766e;\n        text-decoration: underline;\n      }\n    `,\n  ];\n\n  connectedCallback(): void {\n    super.connectedCallback();\n    if (typeof window !== \"undefined\") {\n      window.addEventListener(\"resize\", this.handleResize);\n      window.addEventListener(\n        \"pointerdown\",\n        this.handleGlobalPointerDown as EventListener,\n      );\n\n      // Load state early (before first render) so menu selection is correct\n      this.hydrateStateFromStorageEarly();\n      this.tryAutoAttachCore();\n      this.ensureAnnouncementLoading();\n    }\n  }\n\n  disconnectedCallback(): void {\n    super.disconnectedCallback();\n    if (typeof window !== \"undefined\") {\n      window.removeEventListener(\"resize\", this.handleResize);\n      window.removeEventListener(\n        \"pointerdown\",\n        this.handleGlobalPointerDown as EventListener,\n      );\n    }\n    this.removeDockStyles(); // Clean up any docking styles\n    this.detachFromCore();\n  }\n\n  firstUpdated(): void {\n    if (typeof window === \"undefined\") {\n      return;\n    }\n\n    if (!this._core) {\n      this.tryAutoAttachCore();\n    }\n\n    this.measureContext(\"button\");\n    this.measureContext(\"window\");\n\n    this.contextState.button.anchor = { horizontal: \"right\", vertical: \"top\" };\n    this.contextState.button.anchorOffset = { x: EDGE_MARGIN, y: EDGE_MARGIN };\n\n    this.contextState.window.anchor = { horizontal: \"right\", vertical: \"top\" };\n    this.contextState.window.anchorOffset = { x: EDGE_MARGIN, y: EDGE_MARGIN };\n\n    this.hydrateStateFromStorage();\n\n    // Apply docking styles if open and docked (skip transition on initial load)\n    if (this.isOpen && this.dockMode !== \"floating\") {\n      this.applyDockStyles(true);\n    }\n\n    this.applyAnchorPosition(\"button\");\n\n    if (this.dockMode === \"floating\") {\n      if (this.hasCustomPosition.window) {\n        this.applyAnchorPosition(\"window\");\n      } else {\n        this.centerContext(\"window\");\n      }\n    }\n\n    this.ensureAnnouncementLoading();\n\n    this.updateHostTransform(this.isOpen ? \"window\" : \"button\");\n  }\n\n  render() {\n    return this.isOpen ? this.renderWindow() : this.renderButton();\n  }\n\n  private renderButton() {\n    const buttonClasses = [\n      \"console-button\",\n      \"group\",\n      \"relative\",\n      \"pointer-events-auto\",\n      \"inline-flex\",\n      \"h-12\",\n      \"w-12\",\n      \"items-center\",\n      \"justify-center\",\n      \"rounded-full\",\n      \"border\",\n      \"border-white/20\",\n      \"bg-slate-950/95\",\n      \"text-xs\",\n      \"font-medium\",\n      \"text-white\",\n      \"ring-1\",\n      \"ring-white/10\",\n      \"backdrop-blur-md\",\n      \"transition\",\n      \"hover:border-white/30\",\n      \"hover:bg-slate-900/95\",\n      \"hover:scale-105\",\n      \"focus-visible:outline\",\n      \"focus-visible:outline-2\",\n      \"focus-visible:outline-offset-2\",\n      \"focus-visible:outline-rose-500\",\n      \"touch-none\",\n      \"select-none\",\n      this.isDragging ? \"cursor-grabbing\" : \"cursor-grab\",\n    ].join(\" \");\n\n    return html`\n      <button\n        class=${buttonClasses}\n        type=\"button\"\n        aria-label=\"Web Inspector\"\n        data-drag-context=\"button\"\n        data-dragging=${this.isDragging && this.pointerContext === \"button\"\n          ? \"true\"\n          : \"false\"}\n        @pointerdown=${this.handlePointerDown}\n        @pointermove=${this.handlePointerMove}\n        @pointerup=${this.handlePointerUp}\n        @pointercancel=${this.handlePointerCancel}\n        @click=${this.handleButtonClick}\n      >\n        ${this.renderAnnouncementPreview()}\n        <img\n          src=${inspectorLogoIconUrl}\n          alt=\"Inspector logo\"\n          class=\"h-5 w-auto\"\n          loading=\"lazy\"\n        />\n      </button>\n    `;\n  }\n\n  private renderWindow() {\n    const windowState = this.contextState.window;\n    const isDocked = this.dockMode !== \"floating\";\n    const isTransitioning = this.hasAttribute(\"data-transitioning\");\n\n    const windowStyles = isDocked\n      ? this.getDockedWindowStyles()\n      : {\n          width: `${Math.round(windowState.size.width)}px`,\n          height: `${Math.round(windowState.size.height)}px`,\n          minWidth: `${MIN_WINDOW_WIDTH}px`,\n          minHeight: `${MIN_WINDOW_HEIGHT}px`,\n        };\n\n    const hasContextDropdown = this.contextOptions.length > 0;\n    const contextDropdown = hasContextDropdown\n      ? this.renderContextDropdown()\n      : nothing;\n    const coreStatus = this.getCoreStatusSummary();\n    const agentSelector = hasContextDropdown\n      ? contextDropdown\n      : html`\n          <div\n            class=\"flex items-center gap-2 rounded-md border border-dashed border-gray-200 px-2 py-1 text-xs text-gray-400\"\n          >\n            <span>${this.renderIcon(\"Bot\")}</span>\n            <span class=\"truncate\">No agents available</span>\n          </div>\n        `;\n\n    return html`\n      <section\n        class=\"inspector-window pointer-events-auto relative flex flex-col overflow-hidden rounded-xl border border-gray-200 bg-white text-gray-900 shadow-lg\"\n        style=${styleMap(windowStyles)}\n        data-docked=${isDocked}\n        data-transitioning=${isTransitioning}\n      >\n        ${isDocked\n          ? html`\n              <div\n                class=\"dock-resize-handle pointer-events-auto\"\n                role=\"presentation\"\n                aria-hidden=\"true\"\n                @pointerdown=${this.handleResizePointerDown}\n                @pointermove=${this.handleResizePointerMove}\n                @pointerup=${this.handleResizePointerUp}\n                @pointercancel=${this.handleResizePointerCancel}\n              ></div>\n            `\n          : nothing}\n        <div\n          class=\"flex flex-1 flex-col overflow-hidden bg-white text-gray-800\"\n        >\n          <div\n            class=\"drag-handle relative z-30 flex flex-col border-b border-gray-200 bg-white/95 backdrop-blur-sm ${isDocked\n              ? \"\"\n              : this.isDragging && this.pointerContext === \"window\"\n                ? \"cursor-grabbing\"\n                : \"cursor-grab\"}\"\n            data-drag-context=\"window\"\n            @pointerdown=${isDocked ? undefined : this.handlePointerDown}\n            @pointermove=${isDocked ? undefined : this.handlePointerMove}\n            @pointerup=${isDocked ? undefined : this.handlePointerUp}\n            @pointercancel=${isDocked ? undefined : this.handlePointerCancel}\n          >\n            <div class=\"flex flex-wrap items-center gap-3 px-4 py-3\">\n              <div class=\"flex items-center min-w-0\">\n                <img\n                  src=${inspectorLogoUrl}\n                  alt=\"Inspector logo\"\n                  class=\"h-6 w-auto\"\n                  loading=\"lazy\"\n                />\n              </div>\n              <div class=\"ml-auto flex min-w-0 items-center gap-2\">\n                <div class=\"min-w-[160px] max-w-xs\">${agentSelector}</div>\n                <div class=\"flex items-center gap-1\">\n                  ${this.renderDockControls()}\n                  <button\n                    class=\"flex h-8 w-8 items-center justify-center rounded-md text-gray-400 transition hover:bg-gray-100 hover:text-gray-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400\"\n                    type=\"button\"\n                    aria-label=\"Close Web Inspector\"\n                    @pointerdown=${this.handleClosePointerDown}\n                    @click=${this.handleCloseClick}\n                  >\n                    ${this.renderIcon(\"X\")}\n                  </button>\n                </div>\n              </div>\n            </div>\n            <div\n              class=\"flex flex-wrap items-center gap-2 border-t border-gray-100 px-3 py-2 text-xs\"\n            >\n              ${this.menuItems.map(({ key, label, icon }) => {\n                const isSelected = this.selectedMenu === key;\n                const tabClasses = [\n                  \"inline-flex items-center gap-2 rounded-md px-3 py-2 transition focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-300\",\n                  isSelected\n                    ? \"bg-gray-900 text-white shadow-sm\"\n                    : \"text-gray-600 hover:bg-gray-100 hover:text-gray-900\",\n                ].join(\" \");\n\n                return html`\n                  <button\n                    type=\"button\"\n                    class=${tabClasses}\n                    aria-pressed=${isSelected}\n                    @click=${() => this.handleMenuSelect(key)}\n                  >\n                    <span\n                      class=\"text-gray-400 ${isSelected ? \"text-white\" : \"\"}\"\n                    >\n                      ${this.renderIcon(icon)}\n                    </span>\n                    <span>${label}</span>\n                  </button>\n                `;\n              })}\n            </div>\n          </div>\n          <div class=\"flex flex-1 flex-col overflow-hidden\">\n            <div class=\"flex-1 overflow-auto\">\n              ${this.renderAnnouncementPanel()}\n              ${this.renderCoreWarningBanner()} ${this.renderMainContent()}\n              <slot></slot>\n            </div>\n            <div class=\"border-t border-gray-200 bg-gray-50 px-4 py-2\">\n              <div\n                class=\"flex items-center gap-2 rounded-md px-3 py-2 text-xs ${coreStatus.tone} w-full overflow-hidden my-1\"\n                title=${coreStatus.description}\n              >\n                <span\n                  class=\"flex h-6 w-6 items-center justify-center rounded bg-white/60\"\n                >\n                  ${this.renderIcon(\"Activity\")}\n                </span>\n                <span class=\"font-medium\">${coreStatus.label}</span>\n                <span class=\"truncate text-[11px] opacity-80\"\n                  >${coreStatus.description}</span\n                >\n              </div>\n            </div>\n          </div>\n        </div>\n        <div\n          class=\"resize-handle pointer-events-auto absolute bottom-1 right-1 flex h-5 w-5 cursor-nwse-resize items-center justify-center text-gray-400 transition hover:text-gray-600\"\n          role=\"presentation\"\n          aria-hidden=\"true\"\n          @pointerdown=${this.handleResizePointerDown}\n          @pointermove=${this.handleResizePointerMove}\n          @pointerup=${this.handleResizePointerUp}\n          @pointercancel=${this.handleResizePointerCancel}\n        >\n          <svg\n            class=\"h-3 w-3\"\n            viewBox=\"0 0 16 16\"\n            fill=\"none\"\n            stroke=\"currentColor\"\n            stroke-linecap=\"round\"\n            stroke-width=\"1.5\"\n          >\n            <path d=\"M5 15L15 5\" />\n            <path d=\"M9 15L15 9\" />\n          </svg>\n        </div>\n      </section>\n    `;\n  }\n\n  private hydrateStateFromStorageEarly(): void {\n    if (typeof document === \"undefined\" || typeof window === \"undefined\") {\n      return;\n    }\n\n    const persisted = loadInspectorState(INSPECTOR_STORAGE_KEY);\n    if (!persisted) {\n      return;\n    }\n\n    // Restore the open/closed state\n    if (typeof persisted.isOpen === \"boolean\") {\n      this.isOpen = persisted.isOpen;\n    }\n\n    // Restore the dock mode\n    if (isValidDockMode(persisted.dockMode)) {\n      this.dockMode = persisted.dockMode;\n    }\n\n    // Restore selected menu\n    if (typeof persisted.selectedMenu === \"string\") {\n      const validMenu = this.menuItems.find(\n        (item) => item.key === persisted.selectedMenu,\n      );\n      if (validMenu) {\n        this.selectedMenu = validMenu.key;\n      }\n    }\n\n    // Restore selected context (agent), will be validated later against available agents\n    if (typeof persisted.selectedContext === \"string\") {\n      this.selectedContext = persisted.selectedContext;\n      this.pendingSelectedContext = persisted.selectedContext;\n    }\n  }\n\n  private hydrateStateFromStorage(): void {\n    if (typeof document === \"undefined\" || typeof window === \"undefined\") {\n      return;\n    }\n\n    const persisted = loadInspectorState(INSPECTOR_STORAGE_KEY);\n    if (!persisted) {\n      return;\n    }\n\n    const persistedButton = persisted.button;\n    if (persistedButton) {\n      if (isValidAnchor(persistedButton.anchor)) {\n        this.contextState.button.anchor = persistedButton.anchor;\n      }\n\n      if (isValidPosition(persistedButton.anchorOffset)) {\n        this.contextState.button.anchorOffset = persistedButton.anchorOffset;\n      }\n\n      if (typeof persistedButton.hasCustomPosition === \"boolean\") {\n        this.hasCustomPosition.button = persistedButton.hasCustomPosition;\n      }\n    }\n\n    const persistedWindow = persisted.window;\n    if (persistedWindow) {\n      if (isValidAnchor(persistedWindow.anchor)) {\n        this.contextState.window.anchor = persistedWindow.anchor;\n      }\n\n      if (isValidPosition(persistedWindow.anchorOffset)) {\n        this.contextState.window.anchorOffset = persistedWindow.anchorOffset;\n      }\n\n      if (isValidSize(persistedWindow.size)) {\n        // Now clampWindowSize will use the correct minimum based on dockMode\n        this.contextState.window.size = this.clampWindowSize(\n          persistedWindow.size,\n        );\n      }\n\n      if (typeof persistedWindow.hasCustomPosition === \"boolean\") {\n        this.hasCustomPosition.window = persistedWindow.hasCustomPosition;\n      }\n    }\n\n    if (typeof persisted.selectedContext === \"string\") {\n      this.selectedContext = persisted.selectedContext;\n      this.pendingSelectedContext = persisted.selectedContext;\n    }\n  }\n\n  private get activeContext(): ContextKey {\n    return this.isOpen ? \"window\" : \"button\";\n  }\n\n  private handlePointerDown = (event: PointerEvent) => {\n    // Don't allow dragging when docked\n    if (this.dockMode !== \"floating\" && this.isOpen) {\n      return;\n    }\n\n    const target = event.currentTarget as HTMLElement | null;\n    const contextAttr = target?.dataset.dragContext;\n    const context: ContextKey = contextAttr === \"window\" ? \"window\" : \"button\";\n\n    const eventTarget = event.target as HTMLElement | null;\n    if (context === \"window\" && eventTarget?.closest(\"button\")) {\n      return;\n    }\n\n    this.pointerContext = context;\n    this.measureContext(context);\n\n    event.preventDefault();\n\n    this.pointerId = event.pointerId;\n    this.dragStart = { x: event.clientX, y: event.clientY };\n    const state = this.contextState[context];\n    this.dragOffset = {\n      x: event.clientX - state.position.x,\n      y: event.clientY - state.position.y,\n    };\n    this.isDragging = false;\n    this.draggedDuringInteraction = false;\n    this.ignoreNextButtonClick = false;\n\n    target?.setPointerCapture?.(this.pointerId);\n  };\n\n  private handlePointerMove = (event: PointerEvent) => {\n    if (\n      this.pointerId !== event.pointerId ||\n      !this.dragStart ||\n      !this.pointerContext\n    ) {\n      return;\n    }\n\n    const distance = Math.hypot(\n      event.clientX - this.dragStart.x,\n      event.clientY - this.dragStart.y,\n    );\n    if (!this.isDragging && distance < DRAG_THRESHOLD) {\n      return;\n    }\n\n    event.preventDefault();\n    this.setDragging(true);\n    this.draggedDuringInteraction = true;\n\n    const desired: Position = {\n      x: event.clientX - this.dragOffset.x,\n      y: event.clientY - this.dragOffset.y,\n    };\n\n    const constrained = this.constrainToViewport(desired, this.pointerContext);\n    this.contextState[this.pointerContext].position = constrained;\n    this.updateHostTransform(this.pointerContext);\n  };\n\n  private handlePointerUp = (event: PointerEvent) => {\n    if (this.pointerId !== event.pointerId) {\n      return;\n    }\n\n    const target = event.currentTarget as HTMLElement | null;\n    if (target?.hasPointerCapture(this.pointerId)) {\n      target.releasePointerCapture(this.pointerId);\n    }\n\n    const context = this.pointerContext ?? this.activeContext;\n\n    if (this.isDragging && this.pointerContext) {\n      event.preventDefault();\n      this.setDragging(false);\n      if (this.pointerContext === \"window\") {\n        this.updateAnchorFromPosition(this.pointerContext);\n        this.hasCustomPosition.window = true;\n        this.applyAnchorPosition(this.pointerContext);\n      } else if (this.pointerContext === \"button\") {\n        // Snap button to nearest corner\n        this.snapButtonToCorner();\n        this.hasCustomPosition.button = true;\n        if (this.draggedDuringInteraction) {\n          this.ignoreNextButtonClick = true;\n        }\n      }\n    } else if (\n      context === \"button\" &&\n      !this.isOpen &&\n      !this.draggedDuringInteraction\n    ) {\n      this.openInspector();\n    }\n\n    this.resetPointerTracking();\n  };\n\n  private handlePointerCancel = (event: PointerEvent) => {\n    if (this.pointerId !== event.pointerId) {\n      return;\n    }\n\n    const target = event.currentTarget as HTMLElement | null;\n    if (target?.hasPointerCapture(this.pointerId)) {\n      target.releasePointerCapture(this.pointerId);\n    }\n\n    this.resetPointerTracking();\n  };\n\n  private handleButtonClick = (event: Event) => {\n    if (this.isDragging) {\n      event.preventDefault();\n      return;\n    }\n\n    if (this.ignoreNextButtonClick) {\n      event.preventDefault();\n      this.ignoreNextButtonClick = false;\n      return;\n    }\n\n    if (!this.isOpen) {\n      event.preventDefault();\n      this.openInspector();\n    }\n  };\n\n  private handleClosePointerDown = (event: PointerEvent) => {\n    event.stopPropagation();\n    event.preventDefault();\n  };\n\n  private handleCloseClick = () => {\n    this.closeInspector();\n  };\n\n  private handleResizePointerDown = (event: PointerEvent) => {\n    event.stopPropagation();\n    event.preventDefault();\n\n    this.hasCustomPosition.window = true;\n    this.isResizing = true;\n    this.resizePointerId = event.pointerId;\n    this.resizeStart = { x: event.clientX, y: event.clientY };\n    this.resizeInitialSize = { ...this.contextState.window.size };\n\n    // Remove transition from body during resize to prevent lag\n    if (document.body && this.dockMode !== \"floating\") {\n      document.body.style.transition = \"\";\n    }\n\n    const target = event.currentTarget as HTMLElement | null;\n    target?.setPointerCapture?.(event.pointerId);\n  };\n\n  private handleResizePointerMove = (event: PointerEvent) => {\n    if (\n      !this.isResizing ||\n      this.resizePointerId !== event.pointerId ||\n      !this.resizeStart ||\n      !this.resizeInitialSize\n    ) {\n      return;\n    }\n\n    event.preventDefault();\n\n    const deltaX = event.clientX - this.resizeStart.x;\n    const deltaY = event.clientY - this.resizeStart.y;\n    const state = this.contextState.window;\n\n    // For docked states, only resize in the appropriate dimension\n    if (this.dockMode === \"docked-left\") {\n      // Only resize width for left dock\n      state.size = this.clampWindowSize({\n        width: this.resizeInitialSize.width + deltaX,\n        height: state.size.height,\n      });\n      // Update the body margin\n      if (document.body) {\n        document.body.style.marginLeft = `${state.size.width}px`;\n      }\n    } else {\n      // Full resize for floating mode\n      state.size = this.clampWindowSize({\n        width: this.resizeInitialSize.width + deltaX,\n        height: this.resizeInitialSize.height + deltaY,\n      });\n      this.keepPositionWithinViewport(\"window\");\n      this.updateAnchorFromPosition(\"window\");\n    }\n\n    this.requestUpdate();\n    this.updateHostTransform(\"window\");\n  };\n\n  private handleResizePointerUp = (event: PointerEvent) => {\n    if (this.resizePointerId !== event.pointerId) {\n      return;\n    }\n\n    const target = event.currentTarget as HTMLElement | null;\n    if (target?.hasPointerCapture(this.resizePointerId)) {\n      target.releasePointerCapture(this.resizePointerId);\n    }\n\n    // Only update anchor position for floating mode\n    if (this.dockMode === \"floating\") {\n      this.updateAnchorFromPosition(\"window\");\n      this.applyAnchorPosition(\"window\");\n    }\n\n    // Persist the new size after resize completes\n    this.persistState();\n    this.resetResizeTracking();\n  };\n\n  private handleResizePointerCancel = (event: PointerEvent) => {\n    if (this.resizePointerId !== event.pointerId) {\n      return;\n    }\n\n    const target = event.currentTarget as HTMLElement | null;\n    if (target?.hasPointerCapture(this.resizePointerId)) {\n      target.releasePointerCapture(this.resizePointerId);\n    }\n\n    // Only update anchor position for floating mode\n    if (this.dockMode === \"floating\") {\n      this.updateAnchorFromPosition(\"window\");\n      this.applyAnchorPosition(\"window\");\n    }\n\n    // Persist the new size after resize completes\n    this.persistState();\n    this.resetResizeTracking();\n  };\n\n  private handleResize = () => {\n    this.measureContext(\"button\");\n    this.applyAnchorPosition(\"button\");\n\n    this.measureContext(\"window\");\n    if (this.hasCustomPosition.window) {\n      this.applyAnchorPosition(\"window\");\n    } else {\n      this.centerContext(\"window\");\n    }\n\n    this.updateHostTransform();\n  };\n\n  private measureContext(context: ContextKey): void {\n    const selector =\n      context === \"window\" ? \".inspector-window\" : \".console-button\";\n    const element = this.renderRoot?.querySelector(\n      selector,\n    ) as HTMLElement | null;\n    if (!element) {\n      return;\n    }\n    const fallback =\n      context === \"window\" ? DEFAULT_WINDOW_SIZE : DEFAULT_BUTTON_SIZE;\n    updateSizeFromElement(this.contextState[context], element, fallback);\n  }\n\n  private centerContext(context: ContextKey): void {\n    if (typeof window === \"undefined\") {\n      return;\n    }\n\n    const viewport = this.getViewportSize();\n    centerContextHelper(this.contextState[context], viewport, EDGE_MARGIN);\n\n    if (context === this.activeContext) {\n      this.updateHostTransform(context);\n    }\n\n    this.hasCustomPosition[context] = false;\n    this.persistState();\n  }\n\n  private ensureWindowPlacement(): void {\n    if (typeof window === \"undefined\") {\n      return;\n    }\n\n    if (!this.hasCustomPosition.window) {\n      this.centerContext(\"window\");\n      return;\n    }\n\n    const viewport = this.getViewportSize();\n    keepPositionWithinViewport(this.contextState.window, viewport, EDGE_MARGIN);\n    updateAnchorFromPositionHelper(\n      this.contextState.window,\n      viewport,\n      EDGE_MARGIN,\n    );\n    this.updateHostTransform(\"window\");\n    this.persistState();\n  }\n\n  private constrainToViewport(\n    position: Position,\n    context: ContextKey,\n  ): Position {\n    if (typeof window === \"undefined\") {\n      return position;\n    }\n\n    const viewport = this.getViewportSize();\n    return constrainToViewport(\n      this.contextState[context],\n      position,\n      viewport,\n      EDGE_MARGIN,\n    );\n  }\n\n  private keepPositionWithinViewport(context: ContextKey): void {\n    if (typeof window === \"undefined\") {\n      return;\n    }\n\n    const viewport = this.getViewportSize();\n    keepPositionWithinViewport(\n      this.contextState[context],\n      viewport,\n      EDGE_MARGIN,\n    );\n  }\n\n  private getViewportSize(): Size {\n    if (typeof window === \"undefined\") {\n      return { ...DEFAULT_WINDOW_SIZE };\n    }\n\n    return { width: window.innerWidth, height: window.innerHeight };\n  }\n\n  private persistState(): void {\n    const state: PersistedState = {\n      button: {\n        anchor: this.contextState.button.anchor,\n        anchorOffset: this.contextState.button.anchorOffset,\n        hasCustomPosition: this.hasCustomPosition.button,\n      },\n      window: {\n        anchor: this.contextState.window.anchor,\n        anchorOffset: this.contextState.window.anchorOffset,\n        size: {\n          width: Math.round(this.contextState.window.size.width),\n          height: Math.round(this.contextState.window.size.height),\n        },\n        hasCustomPosition: this.hasCustomPosition.window,\n      },\n      isOpen: this.isOpen,\n      dockMode: this.dockMode,\n      selectedMenu: this.selectedMenu,\n      selectedContext: this.selectedContext,\n    };\n    saveInspectorState(INSPECTOR_STORAGE_KEY, state);\n    this.pendingSelectedContext = state.selectedContext ?? null;\n  }\n\n  private clampWindowSize(size: Size): Size {\n    // Use smaller minimum width when docked left\n    const minWidth =\n      this.dockMode === \"docked-left\"\n        ? MIN_WINDOW_WIDTH_DOCKED_LEFT\n        : MIN_WINDOW_WIDTH;\n\n    if (typeof window === \"undefined\") {\n      return {\n        width: Math.max(minWidth, size.width),\n        height: Math.max(MIN_WINDOW_HEIGHT, size.height),\n      };\n    }\n\n    const viewport = this.getViewportSize();\n    return clampSizeToViewport(\n      size,\n      viewport,\n      EDGE_MARGIN,\n      minWidth,\n      MIN_WINDOW_HEIGHT,\n    );\n  }\n\n  private setDockMode(mode: DockMode): void {\n    if (this.dockMode === mode) {\n      return;\n    }\n\n    // Add transition class for smooth dock mode changes\n    this.startHostTransition();\n\n    // Clean up previous dock state\n    this.removeDockStyles();\n\n    this.dockMode = mode;\n\n    if (mode !== \"floating\") {\n      // For docking, set the target size immediately so body margins are correct\n      if (mode === \"docked-left\") {\n        this.contextState.window.size.width = DOCKED_LEFT_WIDTH;\n      }\n\n      // Then apply dock styles with correct sizes\n      this.applyDockStyles();\n    } else {\n      // When floating, set size first then center\n      this.contextState.window.size = { ...DEFAULT_WINDOW_SIZE };\n      this.centerContext(\"window\");\n    }\n\n    this.persistState();\n    this.requestUpdate();\n    this.updateHostTransform(\"window\");\n  }\n\n  private startHostTransition(duration = 300): void {\n    this.setAttribute(\"data-transitioning\", \"true\");\n\n    if (this.transitionTimeoutId !== null) {\n      clearTimeout(this.transitionTimeoutId);\n    }\n\n    this.transitionTimeoutId = setTimeout(() => {\n      this.removeAttribute(\"data-transitioning\");\n      this.transitionTimeoutId = null;\n    }, duration);\n  }\n\n  private applyDockStyles(skipTransition = false): void {\n    if (typeof document === \"undefined\" || !document.body) {\n      return;\n    }\n\n    // Save original body margins\n    const computedStyle = window.getComputedStyle(document.body);\n    this.previousBodyMargins = {\n      left: computedStyle.marginLeft,\n      bottom: computedStyle.marginBottom,\n    };\n\n    // Apply transition to body for smooth animation (only when docking, not during resize or initial load)\n    if (!this.isResizing && !skipTransition) {\n      document.body.style.transition = \"margin 300ms ease\";\n    }\n\n    // Apply body margins with the actual window sizes\n    if (this.dockMode === \"docked-left\") {\n      document.body.style.marginLeft = `${this.contextState.window.size.width}px`;\n    }\n\n    // Remove transition after animation completes\n    if (!this.isResizing && !skipTransition) {\n      setTimeout(() => {\n        if (document.body) {\n          document.body.style.transition = \"\";\n        }\n      }, 300);\n    }\n  }\n\n  private removeDockStyles(): void {\n    if (typeof document === \"undefined\" || !document.body) {\n      return;\n    }\n\n    // Only add transition if not resizing\n    if (!this.isResizing) {\n      document.body.style.transition = \"margin 300ms ease\";\n    }\n\n    // Restore original margins if saved\n    if (this.previousBodyMargins) {\n      document.body.style.marginLeft = this.previousBodyMargins.left;\n      document.body.style.marginBottom = this.previousBodyMargins.bottom;\n      this.previousBodyMargins = null;\n    } else {\n      // Reset to default if no previous values\n      document.body.style.marginLeft = \"\";\n      document.body.style.marginBottom = \"\";\n    }\n\n    // Clean up transition after animation completes\n    setTimeout(() => {\n      if (document.body) {\n        document.body.style.transition = \"\";\n      }\n    }, 300);\n  }\n\n  private updateHostTransform(context: ContextKey = this.activeContext): void {\n    if (context !== this.activeContext) {\n      return;\n    }\n\n    // For docked states, CSS handles positioning with fixed positioning\n    if (this.isOpen && this.dockMode === \"docked-left\") {\n      this.style.transform = `translate3d(0, 0, 0)`;\n    } else {\n      const { position } = this.contextState[context];\n      this.style.transform = `translate3d(${position.x}px, ${position.y}px, 0)`;\n    }\n  }\n\n  private setDragging(value: boolean): void {\n    if (this.isDragging !== value) {\n      this.isDragging = value;\n      this.requestUpdate();\n    }\n  }\n\n  private updateAnchorFromPosition(context: ContextKey): void {\n    if (typeof window === \"undefined\") {\n      return;\n    }\n    const viewport = this.getViewportSize();\n    updateAnchorFromPositionHelper(\n      this.contextState[context],\n      viewport,\n      EDGE_MARGIN,\n    );\n  }\n\n  private snapButtonToCorner(): void {\n    if (typeof window === \"undefined\") {\n      return;\n    }\n\n    const viewport = this.getViewportSize();\n    const state = this.contextState.button;\n\n    // Determine which corner is closest based on center of button\n    const centerX = state.position.x + state.size.width / 2;\n    const centerY = state.position.y + state.size.height / 2;\n\n    const horizontal: Anchor[\"horizontal\"] =\n      centerX < viewport.width / 2 ? \"left\" : \"right\";\n    const vertical: Anchor[\"vertical\"] =\n      centerY < viewport.height / 2 ? \"top\" : \"bottom\";\n\n    // Set anchor to nearest corner\n    state.anchor = { horizontal, vertical };\n\n    // Always use EDGE_MARGIN as offset (pinned to corner)\n    state.anchorOffset = { x: EDGE_MARGIN, y: EDGE_MARGIN };\n\n    // Apply the anchor position to snap to corner\n    this.startHostTransition();\n    this.applyAnchorPosition(\"button\");\n  }\n\n  private applyAnchorPosition(context: ContextKey): void {\n    if (typeof window === \"undefined\") {\n      return;\n    }\n    const viewport = this.getViewportSize();\n    applyAnchorPositionHelper(\n      this.contextState[context],\n      viewport,\n      EDGE_MARGIN,\n    );\n    this.updateHostTransform(context);\n    this.persistState();\n  }\n\n  private resetResizeTracking(): void {\n    this.resizePointerId = null;\n    this.resizeStart = null;\n    this.resizeInitialSize = null;\n    this.isResizing = false;\n  }\n\n  private resetPointerTracking(): void {\n    this.pointerId = null;\n    this.dragStart = null;\n    this.pointerContext = null;\n    this.setDragging(false);\n    this.draggedDuringInteraction = false;\n  }\n\n  private openInspector(): void {\n    if (this.isOpen) {\n      return;\n    }\n\n    this.showAnnouncementPreview = false; // hide the bubble once the inspector is opened\n\n    this.ensureAnnouncementLoading();\n\n    this.isOpen = true;\n    this.persistState(); // Save the open state\n\n    // Apply docking styles if in docked mode\n    if (this.dockMode !== \"floating\") {\n      this.applyDockStyles();\n    }\n\n    this.ensureWindowPlacement();\n    this.requestUpdate();\n    void this.updateComplete.then(() => {\n      this.measureContext(\"window\");\n      if (this.dockMode === \"floating\") {\n        if (this.hasCustomPosition.window) {\n          this.applyAnchorPosition(\"window\");\n        } else {\n          this.centerContext(\"window\");\n        }\n      } else {\n        // Update transform for docked position\n        this.updateHostTransform(\"window\");\n      }\n    });\n  }\n\n  private closeInspector(): void {\n    if (!this.isOpen) {\n      return;\n    }\n\n    this.isOpen = false;\n\n    // Remove docking styles when closing\n    if (this.dockMode !== \"floating\") {\n      this.removeDockStyles();\n    }\n\n    this.persistState(); // Save the closed state\n    this.updateHostTransform(\"button\");\n    this.requestUpdate();\n    void this.updateComplete.then(() => {\n      this.measureContext(\"button\");\n      this.applyAnchorPosition(\"button\");\n    });\n  }\n\n  private renderIcon(name: LucideIconName) {\n    const iconNode = icons[name];\n    if (!iconNode) {\n      return nothing;\n    }\n\n    const svgAttrs: Record<string, string | number> = {\n      xmlns: \"http://www.w3.org/2000/svg\",\n      viewBox: \"0 0 24 24\",\n      fill: \"none\",\n      stroke: \"currentColor\",\n      \"stroke-width\": \"1.5\",\n      \"stroke-linecap\": \"round\",\n      \"stroke-linejoin\": \"round\",\n      class: \"h-3.5 w-3.5\",\n    };\n\n    const svgMarkup = `<svg ${this.serializeAttributes(svgAttrs)}>${iconNode\n      .map(([tag, attrs]) => `<${tag} ${this.serializeAttributes(attrs)} />`)\n      .join(\"\")}</svg>`;\n\n    return unsafeHTML(svgMarkup);\n  }\n\n  private renderDockControls() {\n    if (this.dockMode === \"floating\") {\n      // Show dock left button\n      return html`\n        <button\n          class=\"flex h-8 w-8 items-center justify-center rounded-md text-gray-400 transition hover:bg-gray-100 hover:text-gray-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400\"\n          type=\"button\"\n          aria-label=\"Dock to left\"\n          title=\"Dock Left\"\n          @click=${() => this.handleDockClick(\"docked-left\")}\n        >\n          ${this.renderIcon(\"PanelLeft\")}\n        </button>\n      `;\n    } else {\n      // Show float button\n      return html`\n        <button\n          class=\"flex h-8 w-8 items-center justify-center rounded-md text-gray-400 transition hover:bg-gray-100 hover:text-gray-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400\"\n          type=\"button\"\n          aria-label=\"Float window\"\n          title=\"Float\"\n          @click=${() => this.handleDockClick(\"floating\")}\n        >\n          ${this.renderIcon(\"Maximize2\")}\n        </button>\n      `;\n    }\n  }\n\n  private getDockedWindowStyles(): Record<string, string> {\n    if (this.dockMode === \"docked-left\") {\n      return {\n        position: \"fixed\",\n        top: \"0\",\n        left: \"0\",\n        bottom: \"0\",\n        width: `${Math.round(this.contextState.window.size.width)}px`,\n        height: \"100vh\",\n        minWidth: `${MIN_WINDOW_WIDTH_DOCKED_LEFT}px`,\n        borderRadius: \"0\",\n      };\n    }\n    // Default to floating styles\n    return {\n      width: `${Math.round(this.contextState.window.size.width)}px`,\n      height: `${Math.round(this.contextState.window.size.height)}px`,\n      minWidth: `${MIN_WINDOW_WIDTH}px`,\n      minHeight: `${MIN_WINDOW_HEIGHT}px`,\n    };\n  }\n\n  private handleDockClick(mode: DockMode): void {\n    this.setDockMode(mode);\n  }\n\n  private serializeAttributes(\n    attributes: Record<string, string | number | undefined>,\n  ): string {\n    return Object.entries(attributes)\n      .filter(\n        ([key, value]) =>\n          key !== \"key\" &&\n          value !== undefined &&\n          value !== null &&\n          value !== \"\",\n      )\n      .map(\n        ([key, value]) => `${key}=\"${String(value).replace(/\"/g, \"&quot;\")}\"`,\n      )\n      .join(\" \");\n  }\n\n  private sanitizeForLogging(\n    value: unknown,\n    depth = 0,\n    seen = new WeakSet<object>(),\n  ): SanitizedValue {\n    if (value === undefined) {\n      return \"[undefined]\";\n    }\n\n    if (\n      value === null ||\n      typeof value === \"number\" ||\n      typeof value === \"boolean\"\n    ) {\n      return value;\n    }\n\n    if (typeof value === \"string\") {\n      return value;\n    }\n\n    if (\n      typeof value === \"bigint\" ||\n      typeof value === \"symbol\" ||\n      typeof value === \"function\"\n    ) {\n      return String(value);\n    }\n\n    if (value instanceof Date) {\n      return value.toISOString();\n    }\n\n    if (Array.isArray(value)) {\n      if (depth >= 4) {\n        return \"[Truncated depth]\" as SanitizedValue;\n      }\n      return value.map((item) =>\n        this.sanitizeForLogging(item, depth + 1, seen),\n      );\n    }\n\n    if (typeof value === \"object\") {\n      if (seen.has(value as object)) {\n        return \"[Circular]\" as SanitizedValue;\n      }\n      seen.add(value as object);\n\n      if (depth >= 4) {\n        return \"[Truncated depth]\" as SanitizedValue;\n      }\n\n      const result: Record<string, SanitizedValue> = {};\n      for (const [key, entry] of Object.entries(\n        value as Record<string, unknown>,\n      )) {\n        result[key] = this.sanitizeForLogging(entry, depth + 1, seen);\n      }\n      return result;\n    }\n\n    return String(value);\n  }\n\n  private normalizeEventPayload(\n    _type: InspectorAgentEventType,\n    payload: unknown,\n  ): SanitizedValue {\n    if (payload && typeof payload === \"object\" && \"event\" in payload) {\n      const { event, ...rest } = payload as Record<string, unknown>;\n      const cleaned =\n        Object.keys(rest).length === 0 ? event : { event, ...rest };\n      return this.sanitizeForLogging(cleaned);\n    }\n\n    return this.sanitizeForLogging(payload);\n  }\n\n  private normalizeMessageContent(content: unknown): string {\n    if (typeof content === \"string\") {\n      return content;\n    }\n\n    if (\n      content &&\n      typeof content === \"object\" &&\n      \"text\" in (content as Record<string, unknown>)\n    ) {\n      const maybeText = (content as Record<string, unknown>).text;\n      if (typeof maybeText === \"string\") {\n        return maybeText;\n      }\n    }\n\n    if (content === null || content === undefined) {\n      return \"\";\n    }\n\n    if (typeof content === \"object\") {\n      try {\n        return JSON.stringify(this.sanitizeForLogging(content));\n      } catch {\n        return \"\";\n      }\n    }\n\n    return String(content);\n  }\n\n  private normalizeToolCalls(raw: unknown): InspectorToolCall[] {\n    if (!Array.isArray(raw)) {\n      return [];\n    }\n\n    return raw\n      .map((entry) => {\n        if (!entry || typeof entry !== \"object\") {\n          return null;\n        }\n        const call = entry as Record<string, unknown>;\n        const fn = call.function as Record<string, unknown> | undefined;\n        const functionName =\n          typeof fn?.name === \"string\"\n            ? fn.name\n            : typeof call.toolName === \"string\"\n              ? call.toolName\n              : undefined;\n        const args =\n          fn && \"arguments\" in fn\n            ? (fn as Record<string, unknown>).arguments\n            : call.arguments;\n\n        const normalized: InspectorToolCall = {\n          id: typeof call.id === \"string\" ? call.id : undefined,\n          toolName:\n            typeof call.toolName === \"string\" ? call.toolName : functionName,\n          status: typeof call.status === \"string\" ? call.status : undefined,\n        };\n\n        if (functionName) {\n          normalized.function = {\n            name: functionName,\n            arguments: this.sanitizeForLogging(args),\n          };\n        }\n\n        return normalized;\n      })\n      .filter((call): call is InspectorToolCall => Boolean(call));\n  }\n\n  private normalizeAgentMessage(message: unknown): InspectorMessage | null {\n    if (!message || typeof message !== \"object\") {\n      return null;\n    }\n\n    const raw = message as Record<string, unknown>;\n    const role = typeof raw.role === \"string\" ? raw.role : \"unknown\";\n    const contentText = this.normalizeMessageContent(raw.content);\n    const toolCalls = this.normalizeToolCalls(raw.toolCalls);\n\n    return {\n      id: typeof raw.id === \"string\" ? raw.id : undefined,\n      role,\n      contentText,\n      contentRaw:\n        raw.content !== undefined\n          ? this.sanitizeForLogging(raw.content)\n          : undefined,\n      toolCalls,\n    };\n  }\n\n  private normalizeAgentMessages(messages: unknown): InspectorMessage[] | null {\n    if (!Array.isArray(messages)) {\n      return null;\n    }\n\n    const normalized = messages\n      .map((message) => this.normalizeAgentMessage(message))\n      .filter((msg): msg is InspectorMessage => msg !== null);\n\n    return normalized;\n  }\n\n  private normalizeContextStore(\n    context: Readonly<Record<string, unknown>> | null | undefined,\n  ): Record<string, { description?: string; value: unknown }> {\n    if (!context || typeof context !== \"object\") {\n      return {};\n    }\n\n    const normalized: Record<string, { description?: string; value: unknown }> =\n      {};\n    for (const [key, entry] of Object.entries(context)) {\n      if (\n        entry &&\n        typeof entry === \"object\" &&\n        \"value\" in (entry as Record<string, unknown>)\n      ) {\n        const candidate = entry as Record<string, unknown>;\n        const description =\n          typeof candidate.description === \"string\" &&\n          candidate.description.trim().length > 0\n            ? candidate.description\n            : undefined;\n        normalized[key] = { description, value: candidate.value };\n      } else {\n        normalized[key] = { value: entry };\n      }\n    }\n\n    return normalized;\n  }\n\n  private contextOptions: Array<{ key: string; label: string }> = [\n    { key: \"all-agents\", label: \"All Agents\" },\n  ];\n\n  private selectedContext = \"all-agents\";\n  private expandedRows: Set<string> = new Set();\n  private copiedEvents: Set<string> = new Set();\n  private expandedTools: Set<string> = new Set();\n  private expandedContextItems: Set<string> = new Set();\n  private copiedContextItems: Set<string> = new Set();\n\n  private getSelectedMenu(): MenuItem {\n    const found = this.menuItems.find((item) => item.key === this.selectedMenu);\n    return found ?? this.menuItems[0]!;\n  }\n\n  private renderCoreWarningBanner() {\n    if (this._core) {\n      return nothing;\n    }\n\n    return html`\n      <div\n        class=\"mx-4 my-3 flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800\"\n      >\n        <span class=\"mt-0.5 shrink-0 text-amber-600\"\n          >${this.renderIcon(\"AlertTriangle\")}</span\n        >\n        <div class=\"space-y-1\">\n          <div class=\"font-semibold text-amber-900\">\n            CopilotKit core not attached\n          </div>\n          <p class=\"text-[11px] leading-snug text-amber-800\">\n            Pass a live <code>CopilotKitCore</code> instance to\n            <code>&lt;cpk-web-inspector&gt;</code> or expose it on\n            <code>window.__COPILOTKIT_CORE__</code> for auto-attach.\n          </p>\n        </div>\n      </div>\n    `;\n  }\n\n  private getCoreStatusSummary(): {\n    label: string;\n    tone: string;\n    description: string;\n  } {\n    if (!this._core) {\n      return {\n        label: \"Core not attached\",\n        tone: \"border border-amber-200 bg-amber-50 text-amber-800\",\n        description:\n          \"Pass a CopilotKitCore instance to <cpk-web-inspector> or enable auto-attach.\",\n      };\n    }\n\n    const status =\n      this.runtimeStatus ?? CopilotKitCoreRuntimeConnectionStatus.Disconnected;\n    const lastErrorMessage = this.lastCoreError?.message;\n\n    if (status === CopilotKitCoreRuntimeConnectionStatus.Error) {\n      return {\n        label: \"Runtime error\",\n        tone: \"border border-rose-200 bg-rose-50 text-rose-700\",\n        description:\n          lastErrorMessage ?? \"CopilotKit runtime reported an error.\",\n      };\n    }\n\n    if (status === CopilotKitCoreRuntimeConnectionStatus.Connecting) {\n      return {\n        label: \"Connecting\",\n        tone: \"border border-amber-200 bg-amber-50 text-amber-800\",\n        description: \"Waiting for CopilotKit runtime to finish connecting.\",\n      };\n    }\n\n    if (status === CopilotKitCoreRuntimeConnectionStatus.Connected) {\n      return {\n        label: \"Connected\",\n        tone: \"border border-emerald-200 bg-emerald-50 text-emerald-700\",\n        description: \"Live runtime connection established.\",\n      };\n    }\n\n    return {\n      label: \"Disconnected\",\n      tone: \"border border-gray-200 bg-gray-50 text-gray-700\",\n      description:\n        lastErrorMessage ?? \"Waiting for CopilotKit runtime to connect.\",\n    };\n  }\n\n  private renderMainContent() {\n    if (this.selectedMenu === \"ag-ui-events\") {\n      return this.renderEventsTable();\n    }\n\n    if (this.selectedMenu === \"agents\") {\n      return this.renderAgentsView();\n    }\n\n    if (this.selectedMenu === \"frontend-tools\") {\n      return this.renderToolsView();\n    }\n\n    if (this.selectedMenu === \"agent-context\") {\n      return this.renderContextView();\n    }\n\n    return nothing;\n  }\n\n  private renderEventsTable() {\n    const events = this.getEventsForSelectedContext();\n    const filteredEvents = this.filterEvents(events);\n    const selectedLabel =\n      this.selectedContext === \"all-agents\"\n        ? \"all agents\"\n        : `agent ${this.selectedContext}`;\n\n    if (events.length === 0) {\n      return html`\n        <div\n          class=\"flex h-full items-center justify-center px-4 py-8 text-center\"\n        >\n          <div class=\"max-w-md\">\n            <div\n              class=\"mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8\"\n            >\n              ${this.renderIcon(\"Zap\")}\n            </div>\n            <p class=\"text-sm text-gray-600\">No events yet</p>\n            <p class=\"mt-2 text-xs text-gray-500\">\n              Trigger an agent run to see live activity.\n            </p>\n          </div>\n        </div>\n      `;\n    }\n\n    if (filteredEvents.length === 0) {\n      return html`\n        <div\n          class=\"flex h-full items-center justify-center px-4 py-8 text-center\"\n        >\n          <div class=\"max-w-md space-y-3\">\n            <div\n              class=\"flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8\"\n            >\n              ${this.renderIcon(\"Filter\")}\n            </div>\n            <p class=\"text-sm text-gray-600\">\n              No events match the current filters.\n            </p>\n            <div>\n              <button\n                type=\"button\"\n                class=\"inline-flex items-center gap-1 rounded-md bg-gray-900 px-3 py-1.5 text-[11px] font-medium text-white transition hover:bg-gray-800\"\n                @click=${this.resetEventFilters}\n              >\n                ${this.renderIcon(\"RefreshCw\")}\n                <span>Reset filters</span>\n              </button>\n            </div>\n          </div>\n        </div>\n      `;\n    }\n\n    return html`\n      <div class=\"flex h-full flex-col\">\n        <div\n          class=\"flex flex-col gap-1.5 border-b border-gray-200 bg-white px-4 py-2.5\"\n        >\n          <div class=\"flex flex-wrap items-center gap-2\">\n            <div class=\"relative min-w-[200px] flex-1\">\n              <input\n                type=\"search\"\n                class=\"w-full rounded-md border border-gray-200 px-3 py-1.5 text-[11px] text-gray-700 shadow-sm outline-none ring-1 ring-transparent transition focus:border-gray-300 focus:ring-gray-200\"\n                placeholder=\"Search agent, type, payload\"\n                .value=${this.eventFilterText}\n                @input=${this.handleEventFilterInput}\n              />\n            </div>\n            <select\n              class=\"w-40 rounded-md border border-gray-200 bg-white px-2 py-1.5 text-[11px] text-gray-700 shadow-sm outline-none transition focus:border-gray-300 focus:ring-2 focus:ring-gray-200\"\n              .value=${this.eventTypeFilter}\n              @change=${this.handleEventTypeChange}\n            >\n              <option value=\"all\">All event types</option>\n              ${AGENT_EVENT_TYPES.map(\n                (type) =>\n                  html`<option value=${type}>\n                    ${type.toLowerCase().replace(/_/g, \" \")}\n                  </option>`,\n              )}\n            </select>\n            <div class=\"flex items-center gap-1 text-[11px]\">\n              <button\n                type=\"button\"\n                class=\"tooltip-target flex h-8 w-8 items-center justify-center rounded-md border border-gray-200 bg-white text-gray-600 transition hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50\"\n                title=\"Reset filters\"\n                data-tooltip=\"Reset filters\"\n                aria-label=\"Reset filters\"\n                @click=${this.resetEventFilters}\n                ?disabled=${!this.eventFilterText &&\n                this.eventTypeFilter === \"all\"}\n              >\n                ${this.renderIcon(\"RotateCw\")}\n              </button>\n              <button\n                type=\"button\"\n                class=\"tooltip-target flex h-8 w-8 items-center justify-center rounded-md border border-gray-200 bg-white text-gray-600 transition hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50\"\n                title=\"Export JSON\"\n                data-tooltip=\"Export JSON\"\n                aria-label=\"Export JSON\"\n                @click=${() => this.exportEvents(filteredEvents)}\n                ?disabled=${filteredEvents.length === 0}\n              >\n                ${this.renderIcon(\"Download\")}\n              </button>\n              <button\n                type=\"button\"\n                class=\"tooltip-target flex h-8 w-8 items-center justify-center rounded-md border border-gray-200 bg-white text-gray-600 transition hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50\"\n                title=\"Clear events\"\n                data-tooltip=\"Clear events\"\n                aria-label=\"Clear events\"\n                @click=${this.handleClearEvents}\n                ?disabled=${events.length === 0}\n              >\n                ${this.renderIcon(\"Trash2\")}\n              </button>\n            </div>\n          </div>\n          <div class=\"text-[11px] text-gray-500\">\n            Showing ${filteredEvents.length} of\n            ${events.length}${this.selectedContext === \"all-agents\"\n              ? \"\"\n              : ` for ${selectedLabel}`}\n          </div>\n        </div>\n        <div class=\"relative h-full w-full overflow-y-auto overflow-x-hidden\">\n          <table class=\"w-full table-fixed border-collapse text-xs box-border\">\n            <thead class=\"sticky top-0 z-10\">\n              <tr class=\"bg-white\">\n                <th\n                  class=\"border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900\"\n                >\n                  Agent\n                </th>\n                <th\n                  class=\"border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900\"\n                >\n                  Time\n                </th>\n                <th\n                  class=\"border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900\"\n                >\n                  Event Type\n                </th>\n                <th\n                  class=\"border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900\"\n                >\n                  AG-UI Event\n                </th>\n              </tr>\n            </thead>\n            <tbody>\n              ${filteredEvents.map((event, index) => {\n                const rowBg = index % 2 === 0 ? \"bg-white\" : \"bg-gray-50/50\";\n                const badgeClasses = this.getEventBadgeClasses(event.type);\n                const extractedEvent = this.extractEventFromPayload(\n                  event.payload,\n                );\n                const inlineEvent =\n                  this.stringifyPayload(extractedEvent, false) || \"—\";\n                const prettyEvent =\n                  this.stringifyPayload(extractedEvent, true) || inlineEvent;\n                const isExpanded = this.expandedRows.has(event.id);\n\n                return html`\n                  <tr\n                    class=\"${rowBg} cursor-pointer transition hover:bg-blue-50/50\"\n                    @click=${() => this.toggleRowExpansion(event.id)}\n                  >\n                    <td\n                      class=\"border-l border-r border-b border-gray-200 px-3 py-2\"\n                    >\n                      <span class=\"font-mono text-[11px] text-gray-600\"\n                        >${event.agentId}</span\n                      >\n                    </td>\n                    <td\n                      class=\"border-r border-b border-gray-200 px-3 py-2 font-mono text-[11px] text-gray-600\"\n                    >\n                      <span title=${new Date(event.timestamp).toLocaleString()}>\n                        ${new Date(event.timestamp).toLocaleTimeString()}\n                      </span>\n                    </td>\n                    <td class=\"border-r border-b border-gray-200 px-3 py-2\">\n                      <span class=${badgeClasses}>${event.type}</span>\n                    </td>\n                    <td\n                      class=\"border-r border-b border-gray-200 px-3 py-2 font-mono text-[10px] text-gray-600 ${isExpanded\n                        ? \"\"\n                        : \"truncate max-w-xs\"}\"\n                    >\n                      ${isExpanded\n                        ? html`\n                            <div class=\"group relative\">\n                              <pre\n                                class=\"m-0 whitespace-pre-wrap break-words text-[10px] font-mono text-gray-600\"\n                              >\n${prettyEvent}</pre\n                              >\n                              <button\n                                class=\"absolute right-0 top-0 cursor-pointer rounded px-2 py-1 text-[10px] opacity-0 transition group-hover:opacity-100 ${this.copiedEvents.has(\n                                  event.id,\n                                )\n                                  ? \"bg-green-100 text-green-700\"\n                                  : \"bg-gray-100 text-gray-600 hover:bg-gray-200 hover:text-gray-900\"}\"\n                                @click=${(e: Event) => {\n                                  e.stopPropagation();\n                                  this.copyToClipboard(prettyEvent, event.id);\n                                }}\n                              >\n                                ${this.copiedEvents.has(event.id)\n                                  ? html`<span>✓ Copied</span>`\n                                  : html`<span>Copy</span>`}\n                              </button>\n                            </div>\n                          `\n                        : inlineEvent}\n                    </td>\n                  </tr>\n                `;\n              })}\n            </tbody>\n          </table>\n        </div>\n      </div>\n    `;\n  }\n\n  private handleEventFilterInput(event: Event): void {\n    const target = event.target as HTMLInputElement | null;\n    this.eventFilterText = target?.value ?? \"\";\n    this.requestUpdate();\n  }\n\n  private handleEventTypeChange(event: Event): void {\n    const target = event.target as HTMLSelectElement | null;\n    const value = target?.value as InspectorAgentEventType | \"all\" | undefined;\n    if (!value) {\n      return;\n    }\n    this.eventTypeFilter = value;\n    this.requestUpdate();\n  }\n\n  private resetEventFilters(): void {\n    this.eventFilterText = \"\";\n    this.eventTypeFilter = \"all\";\n    this.requestUpdate();\n  }\n\n  private handleClearEvents = (): void => {\n    if (this.selectedContext === \"all-agents\") {\n      this.agentEvents.clear();\n      this.flattenedEvents = [];\n    } else {\n      this.agentEvents.delete(this.selectedContext);\n      this.flattenedEvents = this.flattenedEvents.filter(\n        (event) => event.agentId !== this.selectedContext,\n      );\n    }\n\n    this.expandedRows.clear();\n    this.copiedEvents.clear();\n    this.requestUpdate();\n  };\n\n  private exportEvents(events: InspectorEvent[]): void {\n    try {\n      const payload = JSON.stringify(events, null, 2);\n      const blob = new Blob([payload], { type: \"application/json\" });\n      const url = URL.createObjectURL(blob);\n      const anchor = document.createElement(\"a\");\n      anchor.href = url;\n      anchor.download = `copilotkit-events-${Date.now()}.json`;\n      anchor.click();\n      URL.revokeObjectURL(url);\n    } catch (error) {\n      console.error(\"Failed to export events\", error);\n    }\n  }\n\n  private renderAgentsView() {\n    // Show message if \"all-agents\" is selected or no agents available\n    if (this.selectedContext === \"all-agents\") {\n      return html`\n        <div\n          class=\"flex h-full items-center justify-center px-4 py-8 text-center\"\n        >\n          <div class=\"max-w-md\">\n            <div\n              class=\"mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8\"\n            >\n              ${this.renderIcon(\"Bot\")}\n            </div>\n            <p class=\"text-sm text-gray-600\">No agent selected</p>\n            <p class=\"mt-2 text-xs text-gray-500\">\n              Select an agent from the dropdown above to view details.\n            </p>\n          </div>\n        </div>\n      `;\n    }\n\n    const agentId = this.selectedContext;\n    const status = this.getAgentStatus(agentId);\n    const stats = this.getAgentStats(agentId);\n    const state = this.getLatestStateForAgent(agentId);\n    const messages = this.getLatestMessagesForAgent(agentId);\n\n    const statusColors = {\n      running: \"bg-emerald-50 text-emerald-700\",\n      idle: \"bg-gray-100 text-gray-600\",\n      error: \"bg-rose-50 text-rose-700\",\n    };\n\n    return html`\n      <div class=\"flex flex-col gap-4 p-4 overflow-auto\">\n        <!-- Agent Overview Card -->\n        <div class=\"rounded-lg border border-gray-200 bg-white p-4\">\n          <div class=\"flex items-start justify-between mb-4\">\n            <div class=\"flex items-center gap-3\">\n              <div\n                class=\"flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600\"\n              >\n                ${this.renderIcon(\"Bot\")}\n              </div>\n              <div>\n                <h3 class=\"font-semibold text-sm text-gray-900\">${agentId}</h3>\n                <span\n                  class=\"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[\n                    status\n                  ]} relative -translate-y-[2px]\"\n                >\n                  <span\n                    class=\"h-1.5 w-1.5 rounded-full ${status === \"running\"\n                      ? \"bg-emerald-500 animate-pulse\"\n                      : status === \"error\"\n                        ? \"bg-rose-500\"\n                        : \"bg-gray-400\"}\"\n                  ></span>\n                  ${status.charAt(0).toUpperCase() + status.slice(1)}\n                </span>\n              </div>\n            </div>\n            ${stats.lastActivity\n              ? html`<span class=\"text-xs text-gray-500\"\n                  >Last activity:\n                  ${new Date(stats.lastActivity).toLocaleTimeString()}</span\n                >`\n              : nothing}\n          </div>\n          <div class=\"grid grid-cols-2 gap-4 md:grid-cols-4\">\n            <button\n              type=\"button\"\n              class=\"rounded-md bg-gray-50 px-3 py-2 text-left transition hover:bg-gray-100 cursor-pointer overflow-hidden\"\n              @click=${() => this.handleMenuSelect(\"ag-ui-events\")}\n              title=\"View all events in AG-UI Events\"\n            >\n              <div class=\"truncate whitespace-nowrap text-xs text-gray-600\">\n                Total Events\n              </div>\n              <div class=\"text-lg font-semibold text-gray-900\">\n                ${stats.totalEvents}\n              </div>\n            </button>\n            <div class=\"rounded-md bg-gray-50 px-3 py-2 overflow-hidden\">\n              <div class=\"truncate whitespace-nowrap text-xs text-gray-600\">\n                Messages\n              </div>\n              <div class=\"text-lg font-semibold text-gray-900\">\n                ${stats.messages}\n              </div>\n            </div>\n            <div class=\"rounded-md bg-gray-50 px-3 py-2 overflow-hidden\">\n              <div class=\"truncate whitespace-nowrap text-xs text-gray-600\">\n                Tool Calls\n              </div>\n              <div class=\"text-lg font-semibold text-gray-900\">\n                ${stats.toolCalls}\n              </div>\n            </div>\n            <div class=\"rounded-md bg-gray-50 px-3 py-2 overflow-hidden\">\n              <div class=\"truncate whitespace-nowrap text-xs text-gray-600\">\n                Errors\n              </div>\n              <div class=\"text-lg font-semibold text-gray-900\">\n                ${stats.errors}\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <!-- Current State Section -->\n        <div class=\"rounded-lg border border-gray-200 bg-white\">\n          <div class=\"border-b border-gray-200 px-4 py-3\">\n            <h4 class=\"text-sm font-semibold text-gray-900\">Current State</h4>\n          </div>\n          <div class=\"overflow-auto p-4\">\n            ${this.hasRenderableState(state)\n              ? html`\n                  <pre\n                    class=\"overflow-auto rounded-md bg-gray-50 p-3 text-xs text-gray-800 max-h-64\"\n                  ><code>${this.formatStateForDisplay(state)}</code></pre>\n                `\n              : html`\n                  <div\n                    class=\"flex h-40 items-center justify-center text-xs text-gray-500\"\n                  >\n                    <div class=\"flex items-center gap-2 text-gray-500\">\n                      <span class=\"text-lg text-gray-400\"\n                        >${this.renderIcon(\"Database\")}</span\n                      >\n                      <span>State is empty</span>\n                    </div>\n                  </div>\n                `}\n          </div>\n        </div>\n\n        <!-- Current Messages Section -->\n        <div class=\"rounded-lg border border-gray-200 bg-white\">\n          <div class=\"border-b border-gray-200 px-4 py-3\">\n            <h4 class=\"text-sm font-semibold text-gray-900\">\n              Current Messages\n            </h4>\n          </div>\n          <div class=\"overflow-auto\">\n            ${messages && messages.length > 0\n              ? html`\n                  <table class=\"w-full text-xs\">\n                    <thead class=\"bg-gray-50\">\n                      <tr>\n                        <th\n                          class=\"px-4 py-2 text-left font-medium text-gray-700\"\n                        >\n                          Role\n                        </th>\n                        <th\n                          class=\"px-4 py-2 text-left font-medium text-gray-700\"\n                        >\n                          Content\n                        </th>\n                      </tr>\n                    </thead>\n                    <tbody class=\"divide-y divide-gray-200\">\n                      ${messages.map((msg) => {\n                        const role = msg.role || \"unknown\";\n                        const roleColors: Record<string, string> = {\n                          user: \"bg-blue-100 text-blue-800\",\n                          assistant: \"bg-green-100 text-green-800\",\n                          system: \"bg-gray-100 text-gray-800\",\n                          tool: \"bg-amber-100 text-amber-800\",\n                          unknown: \"bg-gray-100 text-gray-600\",\n                        };\n\n                        const rawContent = msg.contentText ?? \"\";\n                        const toolCalls = msg.toolCalls ?? [];\n                        const hasContent = rawContent.trim().length > 0;\n                        const contentFallback =\n                          toolCalls.length > 0 ? \"Invoked tool call\" : \"—\";\n\n                        return html`\n                          <tr>\n                            <td class=\"px-4 py-2 align-top\">\n                              <span\n                                class=\"inline-flex rounded px-2 py-0.5 text-[10px] font-medium ${roleColors[\n                                  role\n                                ] || roleColors.unknown}\"\n                              >\n                                ${role}\n                              </span>\n                            </td>\n                            <td class=\"px-4 py-2\">\n                              ${hasContent\n                                ? html`<div\n                                    class=\"max-w-2xl whitespace-pre-wrap break-words text-gray-700\"\n                                  >\n                                    ${rawContent}\n                                  </div>`\n                                : html`<div\n                                    class=\"text-xs italic text-gray-400\"\n                                  >\n                                    ${contentFallback}\n                                  </div>`}\n                              ${role === \"assistant\" && toolCalls.length > 0\n                                ? this.renderToolCallDetails(toolCalls)\n                                : nothing}\n                            </td>\n                          </tr>\n                        `;\n                      })}\n                    </tbody>\n                  </table>\n                `\n              : html`\n                  <div\n                    class=\"flex h-40 items-center justify-center text-xs text-gray-500\"\n                  >\n                    <div class=\"flex items-center gap-2 text-gray-500\">\n                      <span class=\"text-lg text-gray-400\"\n                        >${this.renderIcon(\"MessageSquare\")}</span\n                      >\n                      <span>No messages available</span>\n                    </div>\n                  </div>\n                `}\n          </div>\n        </div>\n      </div>\n    `;\n  }\n\n  private renderContextDropdown() {\n    // Filter out \"all-agents\" when in agents view\n    const filteredOptions =\n      this.selectedMenu === \"agents\"\n        ? this.contextOptions.filter((opt) => opt.key !== \"all-agents\")\n        : this.contextOptions;\n\n    const selectedLabel =\n      filteredOptions.find((opt) => opt.key === this.selectedContext)?.label ??\n      \"\";\n\n    return html`\n      <div\n        class=\"relative z-40 min-w-0 flex-1\"\n        data-context-dropdown-root=\"true\"\n      >\n        <button\n          type=\"button\"\n          class=\"relative z-40 flex w-full min-w-0 max-w-[240px] items-center gap-1.5 rounded-md border border-gray-200 px-2 py-1 text-xs font-medium text-gray-700 transition hover:border-gray-300 hover:bg-gray-50\"\n          @pointerdown=${this.handleContextDropdownToggle}\n        >\n          <span class=\"truncate flex-1 text-left\">${selectedLabel}</span>\n          <span class=\"shrink-0 text-gray-400\"\n            >${this.renderIcon(\"ChevronDown\")}</span\n          >\n        </button>\n        ${this.contextMenuOpen\n          ? html`\n              <div\n                class=\"absolute left-0 z-50 mt-1.5 w-40 rounded-md border border-gray-200 bg-white py-1 shadow-md ring-1 ring-black/5\"\n                data-context-dropdown-root=\"true\"\n              >\n                ${filteredOptions.map(\n                  (option) => html`\n                    <button\n                      type=\"button\"\n                      class=\"flex w-full items-center justify-between px-3 py-1.5 text-left text-xs transition hover:bg-gray-50 focus:bg-gray-50 focus:outline-none\"\n                      data-context-dropdown-root=\"true\"\n                      @click=${() => this.handleContextOptionSelect(option.key)}\n                    >\n                      <span\n                        class=\"truncate ${option.key === this.selectedContext\n                          ? \"text-gray-900 font-medium\"\n                          : \"text-gray-600\"}\"\n                        >${option.label}</span\n                      >\n                      ${option.key === this.selectedContext\n                        ? html`<span class=\"text-gray-500\"\n                            >${this.renderIcon(\"Check\")}</span\n                          >`\n                        : nothing}\n                    </button>\n                  `,\n                )}\n              </div>\n            `\n          : nothing}\n      </div>\n    `;\n  }\n\n  private handleMenuSelect(key: MenuKey): void {\n    if (!this.menuItems.some((item) => item.key === key)) {\n      return;\n    }\n\n    this.selectedMenu = key;\n\n    // If switching to agents view and \"all-agents\" is selected, switch to default or first agent\n    if (key === \"agents\" && this.selectedContext === \"all-agents\") {\n      const agentOptions = this.contextOptions.filter(\n        (opt) => opt.key !== \"all-agents\",\n      );\n      if (agentOptions.length > 0) {\n        // Try to find \"default\" agent first\n        const defaultAgent = agentOptions.find((opt) => opt.key === \"default\");\n        this.selectedContext = defaultAgent\n          ? defaultAgent.key\n          : agentOptions[0]!.key;\n      }\n    }\n\n    this.contextMenuOpen = false;\n    this.persistState();\n    this.requestUpdate();\n  }\n\n  private handleContextDropdownToggle(event: PointerEvent): void {\n    event.preventDefault();\n    event.stopPropagation();\n    this.contextMenuOpen = !this.contextMenuOpen;\n    this.requestUpdate();\n  }\n\n  private handleContextOptionSelect(key: string): void {\n    if (!this.contextOptions.some((option) => option.key === key)) {\n      return;\n    }\n\n    if (this.selectedContext !== key) {\n      this.selectedContext = key;\n      this.expandedRows.clear();\n    }\n\n    this.contextMenuOpen = false;\n    this.persistState();\n    this.requestUpdate();\n  }\n\n  private renderToolsView() {\n    if (!this._core) {\n      return html`\n        <div\n          class=\"flex h-full items-center justify-center px-4 py-8 text-xs text-gray-500\"\n        >\n          No core instance available\n        </div>\n      `;\n    }\n\n    this.refreshToolsSnapshot();\n    const allTools = this.cachedTools;\n\n    if (allTools.length === 0) {\n      return html`\n        <div\n          class=\"flex h-full items-center justify-center px-4 py-8 text-center\"\n        >\n          <div class=\"max-w-md\">\n            <div\n              class=\"mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8\"\n            >\n              ${this.renderIcon(\"Hammer\")}\n            </div>\n            <p class=\"text-sm text-gray-600\">No tools available</p>\n            <p class=\"mt-2 text-xs text-gray-500\">\n              Tools will appear here once agents are configured with tool\n              handlers or renderers.\n            </p>\n          </div>\n        </div>\n      `;\n    }\n\n    // Filter tools by selected agent\n    const filteredTools =\n      this.selectedContext === \"all-agents\"\n        ? allTools\n        : allTools.filter(\n            (tool) => !tool.agentId || tool.agentId === this.selectedContext,\n          );\n\n    return html`\n      <div class=\"flex h-full flex-col overflow-hidden\">\n        <div class=\"overflow-auto p-4\">\n          <div class=\"space-y-3\">\n            ${filteredTools.map((tool) => this.renderToolCard(tool))}\n          </div>\n        </div>\n      </div>\n    `;\n  }\n\n  private extractToolsFromAgents(): InspectorToolDefinition[] {\n    if (!this._core) {\n      return [];\n    }\n\n    const tools: InspectorToolDefinition[] = [];\n\n    // Start with tools registered on the core (frontend tools / HIL)\n    for (const coreTool of this._core.tools ?? []) {\n      tools.push({\n        agentId: coreTool.agentId ?? \"\",\n        name: coreTool.name,\n        description: coreTool.description,\n        parameters: coreTool.parameters,\n        type: \"handler\",\n      });\n    }\n\n    // Augment with agent-level tool handlers/renderers\n    for (const [agentId, agent] of Object.entries(this._core.agents)) {\n      if (!agent) continue;\n\n      // Try to extract tool handlers\n      const handlers = (agent as { toolHandlers?: Record<string, unknown> })\n        .toolHandlers;\n      if (handlers && typeof handlers === \"object\") {\n        for (const [toolName, handler] of Object.entries(handlers)) {\n          if (handler && typeof handler === \"object\") {\n            const handlerObj = handler as Record<string, unknown>;\n            tools.push({\n              agentId,\n              name: toolName,\n              description:\n                (typeof handlerObj.description === \"string\" &&\n                  handlerObj.description) ||\n                (handlerObj.tool as { description?: string } | undefined)\n                  ?.description,\n              parameters:\n                handlerObj.parameters ??\n                (handlerObj.tool as { parameters?: unknown } | undefined)\n                  ?.parameters,\n              type: \"handler\",\n            });\n          }\n        }\n      }\n\n      // Try to extract tool renderers\n      const renderers = (agent as { toolRenderers?: Record<string, unknown> })\n        .toolRenderers;\n      if (renderers && typeof renderers === \"object\") {\n        for (const [toolName, renderer] of Object.entries(renderers)) {\n          // Don't duplicate if we already have it as a handler\n          if (\n            !tools.some((t) => t.agentId === agentId && t.name === toolName)\n          ) {\n            if (renderer && typeof renderer === \"object\") {\n              const rendererObj = renderer as Record<string, unknown>;\n              tools.push({\n                agentId,\n                name: toolName,\n                description:\n                  (typeof rendererObj.description === \"string\" &&\n                    rendererObj.description) ||\n                  (rendererObj.tool as { description?: string } | undefined)\n                    ?.description,\n                parameters:\n                  rendererObj.parameters ??\n                  (rendererObj.tool as { parameters?: unknown } | undefined)\n                    ?.parameters,\n                type: \"renderer\",\n              });\n            }\n          }\n        }\n      }\n    }\n\n    return tools.sort((a, b) => {\n      const agentCompare = a.agentId.localeCompare(b.agentId);\n      if (agentCompare !== 0) return agentCompare;\n      return a.name.localeCompare(b.name);\n    });\n  }\n\n  private renderToolCard(tool: InspectorToolDefinition) {\n    const isExpanded = this.expandedTools.has(`${tool.agentId}:${tool.name}`);\n    const schema = this.extractSchemaInfo(tool.parameters);\n\n    const typeColors = {\n      handler: \"bg-blue-50 text-blue-700 border-blue-200\",\n      renderer: \"bg-purple-50 text-purple-700 border-purple-200\",\n    };\n\n    return html`\n      <div class=\"rounded-lg border border-gray-200 bg-white overflow-hidden\">\n        <button\n          type=\"button\"\n          class=\"w-full px-4 py-3 text-left transition hover:bg-gray-50\"\n          @click=${() =>\n            this.toggleToolExpansion(`${tool.agentId}:${tool.name}`)}\n        >\n          <div class=\"flex items-start justify-between gap-3\">\n            <div class=\"flex-1 min-w-0\">\n              <div class=\"flex items-center gap-2 mb-1\">\n                <span class=\"font-mono text-sm font-semibold text-gray-900\"\n                  >${tool.name}</span\n                >\n                <span\n                  class=\"inline-flex items-center rounded-sm border px-1.5 py-0.5 text-[10px] font-medium ${typeColors[\n                    tool.type\n                  ]}\"\n                >\n                  ${tool.type}\n                </span>\n              </div>\n              <div class=\"flex items-center gap-2 text-xs text-gray-500\">\n                <span class=\"flex items-center gap-1\">\n                  ${this.renderIcon(\"Bot\")}\n                  <span class=\"font-mono\">${tool.agentId}</span>\n                </span>\n                ${schema.properties.length > 0\n                  ? html`\n                      <span class=\"text-gray-300\">•</span>\n                      <span\n                        >${schema.properties.length}\n                        parameter${schema.properties.length !== 1\n                          ? \"s\"\n                          : \"\"}</span\n                      >\n                    `\n                  : nothing}\n              </div>\n              ${tool.description\n                ? html`<p class=\"mt-2 text-xs text-gray-600\">\n                    ${tool.description}\n                  </p>`\n                : nothing}\n            </div>\n            <span\n              class=\"shrink-0 text-gray-400 transition ${isExpanded\n                ? \"rotate-180\"\n                : \"\"}\"\n            >\n              ${this.renderIcon(\"ChevronDown\")}\n            </span>\n          </div>\n        </button>\n\n        ${isExpanded\n          ? html`\n              <div class=\"border-t border-gray-200 bg-gray-50/50 px-4 py-3\">\n                ${schema.properties.length > 0\n                  ? html`\n                      <h5 class=\"mb-3 text-xs font-semibold text-gray-700\">\n                        Parameters\n                      </h5>\n                      <div class=\"space-y-3\">\n                        ${schema.properties.map(\n                          (prop) => html`\n                            <div\n                              class=\"rounded-md border border-gray-200 bg-white p-3\"\n                            >\n                              <div\n                                class=\"flex items-start justify-between gap-2 mb-1\"\n                              >\n                                <span\n                                  class=\"font-mono text-xs font-medium text-gray-900\"\n                                  >${prop.name}</span\n                                >\n                                <div class=\"flex items-center gap-1.5 shrink-0\">\n                                  ${prop.required\n                                    ? html`<span\n                                        class=\"text-[9px] rounded border border-rose-200 bg-rose-50 px-1 py-0.5 font-medium text-rose-700\"\n                                        >required</span\n                                      >`\n                                    : html`<span\n                                        class=\"text-[9px] rounded border border-gray-200 bg-gray-50 px-1 py-0.5 font-medium text-gray-600\"\n                                        >optional</span\n                                      >`}\n                                  ${prop.type\n                                    ? html`<span\n                                        class=\"text-[9px] rounded border border-gray-200 bg-gray-50 px-1 py-0.5 font-mono text-gray-600\"\n                                        >${prop.type}</span\n                                      >`\n                                    : nothing}\n                                </div>\n                              </div>\n                              ${prop.description\n                                ? html`<p class=\"mt-1 text-xs text-gray-600\">\n                                    ${prop.description}\n                                  </p>`\n                                : nothing}\n                              ${prop.defaultValue !== undefined\n                                ? html`\n                                    <div\n                                      class=\"mt-2 flex items-center gap-1.5 text-[10px] text-gray-500\"\n                                    >\n                                      <span>Default:</span>\n                                      <code\n                                        class=\"rounded bg-gray-100 px-1 py-0.5 font-mono\"\n                                        >${JSON.stringify(\n                                          prop.defaultValue,\n                                        )}</code\n                                      >\n                                    </div>\n                                  `\n                                : nothing}\n                              ${prop.enum && prop.enum.length > 0\n                                ? html`\n                                    <div class=\"mt-2\">\n                                      <span class=\"text-[10px] text-gray-500\"\n                                        >Allowed values:</span\n                                      >\n                                      <div class=\"mt-1 flex flex-wrap gap-1\">\n                                        ${prop.enum.map(\n                                          (val) => html`\n                                            <code\n                                              class=\"rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 text-[10px] font-mono text-gray-700\"\n                                              >${JSON.stringify(val)}</code\n                                            >\n                                          `,\n                                        )}\n                                      </div>\n                                    </div>\n                                  `\n                                : nothing}\n                            </div>\n                          `,\n                        )}\n                      </div>\n                    `\n                  : html`\n                      <div\n                        class=\"flex items-center justify-center py-4 text-xs text-gray-500\"\n                      >\n                        <span>No parameters defined</span>\n                      </div>\n                    `}\n              </div>\n            `\n          : nothing}\n      </div>\n    `;\n  }\n\n  private extractSchemaInfo(parameters: unknown): {\n    properties: Array<{\n      name: string;\n      type?: string;\n      description?: string;\n      required: boolean;\n      defaultValue?: unknown;\n      enum?: unknown[];\n    }>;\n  } {\n    const result: {\n      properties: Array<{\n        name: string;\n        type?: string;\n        description?: string;\n        required: boolean;\n        defaultValue?: unknown;\n        enum?: unknown[];\n      }>;\n    } = { properties: [] };\n\n    if (!parameters || typeof parameters !== \"object\") {\n      return result;\n    }\n\n    // Try Zod schema introspection\n    const zodDef = (parameters as { _def?: Record<string, unknown> })._def;\n    if (zodDef && typeof zodDef === \"object\") {\n      // Handle Zod object schema\n      if (zodDef.typeName === \"ZodObject\") {\n        const rawShape = zodDef.shape;\n        const shape =\n          typeof rawShape === \"function\"\n            ? (rawShape as () => Record<string, unknown>)()\n            : (rawShape as Record<string, unknown> | undefined);\n\n        if (!shape || typeof shape !== \"object\") {\n          return result;\n        }\n        const requiredKeys = new Set<string>();\n\n        // Get required fields\n        if (zodDef.unknownKeys === \"strict\" || !zodDef.catchall) {\n          Object.keys(shape || {}).forEach((key) => {\n            const candidate = (shape as Record<string, unknown>)[key];\n            const fieldDef = (\n              candidate as { _def?: Record<string, unknown> } | undefined\n            )?._def;\n            if (fieldDef && !this.isZodOptional(candidate)) {\n              requiredKeys.add(key);\n            }\n          });\n        }\n\n        // Extract properties\n        for (const [key, value] of Object.entries(shape || {})) {\n          const fieldInfo = this.extractZodFieldInfo(value);\n          result.properties.push({\n            name: key,\n            type: fieldInfo.type,\n            description: fieldInfo.description,\n            required: requiredKeys.has(key),\n            defaultValue: fieldInfo.defaultValue,\n            enum: fieldInfo.enum,\n          });\n        }\n      }\n    } else if (\n      (parameters as { type?: string; properties?: Record<string, unknown> })\n        .type === \"object\" &&\n      (parameters as { properties?: Record<string, unknown> }).properties\n    ) {\n      // Handle JSON Schema format\n      const props = (parameters as { properties?: Record<string, unknown> })\n        .properties;\n      const required = new Set(\n        Array.isArray((parameters as { required?: string[] }).required)\n          ? (parameters as { required?: string[] }).required\n          : [],\n      );\n\n      for (const [key, value] of Object.entries(props ?? {})) {\n        const prop = value as Record<string, unknown>;\n        result.properties.push({\n          name: key,\n          type: prop.type as string | undefined,\n          description:\n            typeof prop.description === \"string\" ? prop.description : undefined,\n          required: required.has(key),\n          defaultValue: prop.default,\n          enum: Array.isArray(prop.enum) ? prop.enum : undefined,\n        });\n      }\n    }\n\n    return result;\n  }\n\n  private isZodOptional(zodSchema: unknown): boolean {\n    const schema = zodSchema as { _def?: Record<string, unknown> };\n    if (!schema?._def) return false;\n\n    const def = schema._def;\n\n    // Check if it's explicitly optional or nullable\n    if (def.typeName === \"ZodOptional\" || def.typeName === \"ZodNullable\") {\n      return true;\n    }\n\n    // Check if it has a default value\n    if (def.defaultValue !== undefined) {\n      return true;\n    }\n\n    return false;\n  }\n\n  private extractZodFieldInfo(zodSchema: unknown): {\n    type?: string;\n    description?: string;\n    defaultValue?: unknown;\n    enum?: unknown[];\n  } {\n    const info: {\n      type?: string;\n      description?: string;\n      defaultValue?: unknown;\n      enum?: unknown[];\n    } = {};\n\n    const schema = zodSchema as { _def?: Record<string, unknown> };\n    if (!schema?._def) return info;\n\n    let currentSchema = schema as { _def?: Record<string, unknown> };\n    let def = currentSchema._def as Record<string, unknown>;\n\n    // Unwrap optional/nullable\n    while (\n      def.typeName === \"ZodOptional\" ||\n      def.typeName === \"ZodNullable\" ||\n      def.typeName === \"ZodDefault\"\n    ) {\n      if (def.typeName === \"ZodDefault\" && def.defaultValue !== undefined) {\n        info.defaultValue =\n          typeof def.defaultValue === \"function\"\n            ? def.defaultValue()\n            : def.defaultValue;\n      }\n      currentSchema =\n        (def.innerType as { _def?: Record<string, unknown> }) ?? currentSchema;\n      if (!currentSchema?._def) break;\n      def = currentSchema._def as Record<string, unknown>;\n    }\n\n    // Extract description\n    info.description =\n      typeof def.description === \"string\" ? def.description : undefined;\n\n    const typeName =\n      typeof def.typeName === \"string\" ? def.typeName : undefined;\n\n    // Extract type\n    const typeMap: Record<string, string> = {\n      ZodString: \"string\",\n      ZodNumber: \"number\",\n      ZodBoolean: \"boolean\",\n      ZodArray: \"array\",\n      ZodObject: \"object\",\n      ZodEnum: \"enum\",\n      ZodLiteral: \"literal\",\n      ZodUnion: \"union\",\n      ZodAny: \"any\",\n      ZodUnknown: \"unknown\",\n    };\n    info.type = typeName\n      ? typeMap[typeName] || typeName.replace(\"Zod\", \"\").toLowerCase()\n      : undefined;\n\n    // Extract enum values\n    if (typeName === \"ZodEnum\" && Array.isArray(def.values)) {\n      info.enum = def.values as unknown[];\n    } else if (typeName === \"ZodLiteral\" && def.value !== undefined) {\n      info.enum = [def.value];\n    }\n\n    return info;\n  }\n\n  private toggleToolExpansion(toolId: string): void {\n    if (this.expandedTools.has(toolId)) {\n      this.expandedTools.delete(toolId);\n    } else {\n      this.expandedTools.add(toolId);\n    }\n    this.requestUpdate();\n  }\n\n  private renderContextView() {\n    const contextEntries = Object.entries(this.contextStore);\n\n    if (contextEntries.length === 0) {\n      return html`\n        <div\n          class=\"flex h-full items-center justify-center px-4 py-8 text-center\"\n        >\n          <div class=\"max-w-md\">\n            <div\n              class=\"mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8\"\n            >\n              ${this.renderIcon(\"FileText\")}\n            </div>\n            <p class=\"text-sm text-gray-600\">No context available</p>\n            <p class=\"mt-2 text-xs text-gray-500\">\n              Context will appear here once added to CopilotKit.\n            </p>\n          </div>\n        </div>\n      `;\n    }\n\n    return html`\n      <div class=\"flex h-full flex-col overflow-hidden\">\n        <div class=\"overflow-auto p-4\">\n          <div class=\"space-y-3\">\n            ${contextEntries.map(([id, context]) =>\n              this.renderContextCard(id, context),\n            )}\n          </div>\n        </div>\n      </div>\n    `;\n  }\n\n  private renderContextCard(\n    id: string,\n    context: { description?: string; value: unknown },\n  ) {\n    const isExpanded = this.expandedContextItems.has(id);\n    const valuePreview = this.getContextValuePreview(context.value);\n    const hasValue = context.value !== undefined && context.value !== null;\n    const title = context.description?.trim() || id;\n\n    return html`\n      <div class=\"rounded-lg border border-gray-200 bg-white overflow-hidden\">\n        <button\n          type=\"button\"\n          class=\"w-full px-4 py-3 text-left transition hover:bg-gray-50\"\n          @click=${() => this.toggleContextExpansion(id)}\n        >\n          <div class=\"flex items-start justify-between gap-3\">\n            <div class=\"flex-1 min-w-0\">\n              <p class=\"text-sm font-medium text-gray-900 mb-1\">${title}</p>\n              <div class=\"flex items-center gap-2 text-xs text-gray-500\">\n                <span\n                  class=\"font-mono truncate inline-block align-middle\"\n                  style=\"max-width: 180px;\"\n                  >${id}</span\n                >\n                ${hasValue\n                  ? html`\n                      <span class=\"text-gray-300\">•</span>\n                      <span class=\"truncate\">${valuePreview}</span>\n                    `\n                  : nothing}\n              </div>\n            </div>\n            <span\n              class=\"shrink-0 text-gray-400 transition ${isExpanded\n                ? \"rotate-180\"\n                : \"\"}\"\n            >\n              ${this.renderIcon(\"ChevronDown\")}\n            </span>\n          </div>\n        </button>\n\n        ${isExpanded\n          ? html`\n              <div class=\"border-t border-gray-200 bg-gray-50/50 px-4 py-3\">\n                <div class=\"mb-3\">\n                  <h5 class=\"mb-1 text-xs font-semibold text-gray-700\">ID</h5>\n                  <code\n                    class=\"block rounded bg-white border border-gray-200 px-2 py-1 text-[10px] font-mono text-gray-600\"\n                    >${id}</code\n                  >\n                </div>\n                ${hasValue\n                  ? html`\n                      <div class=\"mb-2 flex items-center justify-between gap-2\">\n                        <h5 class=\"text-xs font-semibold text-gray-700\">\n                          Value\n                        </h5>\n                        <button\n                          class=\"flex items-center gap-1 rounded-md border border-gray-200 bg-white px-2 py-1 text-[10px] font-medium text-gray-700 transition hover:bg-gray-50\"\n                          type=\"button\"\n                          @click=${(e: Event) => {\n                            e.stopPropagation();\n                            void this.copyContextValue(context.value, id);\n                          }}\n                        >\n                          ${this.copiedContextItems.has(id)\n                            ? \"Copied\"\n                            : \"Copy JSON\"}\n                        </button>\n                      </div>\n                      <div\n                        class=\"rounded-md border border-gray-200 bg-white p-3\"\n                      >\n                        <pre\n                          class=\"overflow-auto text-xs text-gray-800 max-h-96\"\n                        ><code>${this.formatContextValue(\n                          context.value,\n                        )}</code></pre>\n                      </div>\n                    `\n                  : html`\n                      <div\n                        class=\"flex items-center justify-center py-4 text-xs text-gray-500\"\n                      >\n                        <span>No value available</span>\n                      </div>\n                    `}\n              </div>\n            `\n          : nothing}\n      </div>\n    `;\n  }\n\n  private getContextValuePreview(value: unknown): string {\n    if (value === undefined || value === null) {\n      return \"—\";\n    }\n\n    if (typeof value === \"string\") {\n      return value.length > 50 ? `${value.substring(0, 50)}...` : value;\n    }\n\n    if (typeof value === \"number\" || typeof value === \"boolean\") {\n      return String(value);\n    }\n\n    if (Array.isArray(value)) {\n      return `Array(${value.length})`;\n    }\n\n    if (typeof value === \"object\") {\n      const keys = Object.keys(value);\n      return `Object with ${keys.length} key${keys.length !== 1 ? \"s\" : \"\"}`;\n    }\n\n    if (typeof value === \"function\") {\n      return \"Function\";\n    }\n\n    return String(value);\n  }\n\n  private formatContextValue(value: unknown): string {\n    if (value === undefined) {\n      return \"undefined\";\n    }\n\n    if (value === null) {\n      return \"null\";\n    }\n\n    if (typeof value === \"function\") {\n      return value.toString();\n    }\n\n    try {\n      return JSON.stringify(value, null, 2);\n    } catch {\n      return String(value);\n    }\n  }\n\n  private async copyContextValue(\n    value: unknown,\n    contextId: string,\n  ): Promise<void> {\n    if (typeof navigator === \"undefined\" || !navigator.clipboard?.writeText) {\n      console.warn(\"Clipboard API is not available in this environment.\");\n      return;\n    }\n\n    const serialized = this.formatContextValue(value);\n    try {\n      await navigator.clipboard.writeText(serialized);\n      this.copiedContextItems.add(contextId);\n      this.requestUpdate();\n      setTimeout(() => {\n        this.copiedContextItems.delete(contextId);\n        this.requestUpdate();\n      }, 1500);\n    } catch (error) {\n      console.error(\"Failed to copy context value:\", error);\n    }\n  }\n\n  private toggleContextExpansion(contextId: string): void {\n    if (this.expandedContextItems.has(contextId)) {\n      this.expandedContextItems.delete(contextId);\n    } else {\n      this.expandedContextItems.add(contextId);\n    }\n    this.requestUpdate();\n  }\n\n  private handleGlobalPointerDown = (event: PointerEvent): void => {\n    if (!this.contextMenuOpen) {\n      return;\n    }\n\n    const clickedDropdown = event.composedPath().some((node) => {\n      return (\n        node instanceof HTMLElement &&\n        node.dataset?.contextDropdownRoot === \"true\"\n      );\n    });\n\n    if (!clickedDropdown) {\n      this.contextMenuOpen = false;\n      this.requestUpdate();\n    }\n  };\n\n  private toggleRowExpansion(eventId: string): void {\n    // Don't toggle if user is selecting text\n    const selection = window.getSelection();\n    if (selection && selection.toString().length > 0) {\n      return;\n    }\n\n    if (this.expandedRows.has(eventId)) {\n      this.expandedRows.delete(eventId);\n    } else {\n      this.expandedRows.add(eventId);\n    }\n    this.requestUpdate();\n  }\n\n  private renderAnnouncementPanel() {\n    if (!this.isOpen) {\n      return nothing;\n    }\n\n    // Ensure loading is triggered even if we mounted in an already-open state\n    this.ensureAnnouncementLoading();\n\n    if (!this.hasUnseenAnnouncement) {\n      return nothing;\n    }\n\n    if (!this.announcementLoaded && !this.announcementMarkdown) {\n      return html`<div\n        class=\"mx-4 my-3 rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-800 shadow-[0_12px_30px_rgba(15,23,42,0.12)]\"\n      >\n        <div class=\"flex items-center gap-2 font-semibold\">\n          <span\n            class=\"inline-flex h-6 w-6 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm\"\n          >\n            ${this.renderIcon(\"Megaphone\")}\n          </span>\n          <span>Loading latest announcement…</span>\n        </div>\n      </div>`;\n    }\n\n    if (this.announcementLoadError) {\n      return html`<div\n        class=\"mx-4 my-3 rounded-xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-900 shadow-[0_12px_30px_rgba(15,23,42,0.12)]\"\n      >\n        <div class=\"flex items-center gap-2 font-semibold\">\n          <span\n            class=\"inline-flex h-6 w-6 items-center justify-center rounded-md bg-rose-600 text-white shadow-sm\"\n          >\n            ${this.renderIcon(\"Megaphone\")}\n          </span>\n          <span>Announcement unavailable</span>\n        </div>\n        <p class=\"mt-2 text-xs text-rose-800\">\n          We couldn’t load the latest notice. Please try opening the inspector\n          again.\n        </p>\n      </div>`;\n    }\n\n    if (!this.announcementMarkdown) {\n      return nothing;\n    }\n\n    const content = this.announcementHtml\n      ? unsafeHTML(this.announcementHtml)\n      : html`<pre class=\"whitespace-pre-wrap text-sm text-gray-900\">\n${this.announcementMarkdown}</pre\n        >`;\n\n    return html`<div\n      class=\"mx-4 my-3 rounded-xl border border-slate-200 bg-white px-4 py-4 shadow-[0_12px_30px_rgba(15,23,42,0.12)]\"\n    >\n      <div\n        class=\"mb-3 flex items-center gap-2 text-sm font-semibold text-slate-900\"\n      >\n        <span\n          class=\"inline-flex h-7 w-7 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm\"\n        >\n          ${this.renderIcon(\"Megaphone\")}\n        </span>\n        <span>Announcement</span>\n        <button\n          class=\"announcement-dismiss ml-auto\"\n          type=\"button\"\n          @click=${this.handleDismissAnnouncement}\n          aria-label=\"Dismiss announcement\"\n        >\n          Dismiss\n        </button>\n      </div>\n      <div class=\"announcement-content text-sm leading-relaxed text-gray-900\">\n        ${content}\n      </div>\n    </div>`;\n  }\n\n  private ensureAnnouncementLoading(): void {\n    if (\n      this.announcementPromise ||\n      typeof window === \"undefined\" ||\n      typeof fetch === \"undefined\"\n    ) {\n      return;\n    }\n    this.announcementPromise = this.fetchAnnouncement();\n  }\n\n  private renderAnnouncementPreview() {\n    if (\n      !this.hasUnseenAnnouncement ||\n      !this.showAnnouncementPreview ||\n      !this.announcementPreviewText\n    ) {\n      return nothing;\n    }\n\n    const side =\n      this.contextState.button.anchor.horizontal === \"left\" ? \"right\" : \"left\";\n\n    return html`<div\n      class=\"announcement-preview\"\n      data-side=${side}\n      role=\"note\"\n      @click=${() => this.handleAnnouncementPreviewClick()}\n    >\n      <span>${this.announcementPreviewText}</span>\n      <span class=\"announcement-preview__arrow\"></span>\n    </div>`;\n  }\n\n  private handleAnnouncementPreviewClick(): void {\n    this.showAnnouncementPreview = false;\n    this.openInspector();\n  }\n\n  private handleDismissAnnouncement = (): void => {\n    this.markAnnouncementSeen();\n  };\n\n  private async fetchAnnouncement(): Promise<void> {\n    try {\n      const response = await fetch(ANNOUNCEMENT_URL, { cache: \"no-cache\" });\n      if (!response.ok) {\n        throw new Error(`Failed to load announcement (${response.status})`);\n      }\n\n      const data = (await response.json()) as {\n        timestamp?: unknown;\n        previewText?: unknown;\n        announcement?: unknown;\n      };\n\n      const timestamp =\n        typeof data?.timestamp === \"string\" ? data.timestamp : null;\n      const previewText =\n        typeof data?.previewText === \"string\" ? data.previewText : null;\n      const markdown =\n        typeof data?.announcement === \"string\" ? data.announcement : null;\n\n      if (!timestamp || !markdown) {\n        throw new Error(\"Malformed announcement payload\");\n      }\n\n      const storedTimestamp = this.loadStoredAnnouncementTimestamp();\n\n      this.announcementTimestamp = timestamp;\n      this.announcementPreviewText = previewText ?? \"\";\n      this.announcementMarkdown = markdown;\n      this.hasUnseenAnnouncement =\n        (!storedTimestamp || storedTimestamp !== timestamp) &&\n        !!this.announcementPreviewText;\n      this.showAnnouncementPreview = this.hasUnseenAnnouncement;\n      this.announcementHtml = await this.convertMarkdownToHtml(markdown);\n      this.announcementLoaded = true;\n\n      this.requestUpdate();\n    } catch (error) {\n      this.announcementLoadError = error;\n      this.announcementLoaded = true;\n      this.requestUpdate();\n    }\n  }\n\n  private async convertMarkdownToHtml(\n    markdown: string,\n  ): Promise<string | null> {\n    const renderer = new marked.Renderer();\n    renderer.link = (href, title, text) => {\n      const safeHref = this.escapeHtmlAttr(this.appendRefParam(href ?? \"\"));\n      const titleAttr = title ? ` title=\"${this.escapeHtmlAttr(title)}\"` : \"\";\n      return `<a href=\"${safeHref}\" target=\"_blank\" rel=\"noopener\"${titleAttr}>${text}</a>`;\n    };\n    return marked.parse(markdown, { renderer });\n  }\n\n  private appendRefParam(href: string): string {\n    try {\n      const url = new URL(\n        href,\n        typeof window !== \"undefined\"\n          ? window.location.href\n          : \"https://copilotkit.ai\",\n      );\n      if (!url.searchParams.has(\"ref\")) {\n        url.searchParams.append(\"ref\", \"cpk-inspector\");\n      }\n      return url.toString();\n    } catch {\n      return href;\n    }\n  }\n\n  private escapeHtmlAttr(value: string): string {\n    return value\n      .replace(/&/g, \"&amp;\")\n      .replace(/</g, \"&lt;\")\n      .replace(/>/g, \"&gt;\")\n      .replace(/\\\"/g, \"&quot;\")\n      .replace(/'/g, \"&#39;\");\n  }\n\n  private loadStoredAnnouncementTimestamp(): string | null {\n    if (typeof window === \"undefined\" || !window.localStorage) {\n      return null;\n    }\n    try {\n      const raw = window.localStorage.getItem(ANNOUNCEMENT_STORAGE_KEY);\n      if (!raw) {\n        return null;\n      }\n      const parsed = JSON.parse(raw);\n      if (parsed && typeof parsed.timestamp === \"string\") {\n        return parsed.timestamp;\n      }\n      // Backward compatibility: previous shape { hash }\n      return null;\n    } catch {\n      // ignore malformed storage\n    }\n    return null;\n  }\n\n  private persistAnnouncementTimestamp(timestamp: string): void {\n    if (typeof window === \"undefined\" || !window.localStorage) {\n      return;\n    }\n    try {\n      const payload = JSON.stringify({ timestamp });\n      window.localStorage.setItem(ANNOUNCEMENT_STORAGE_KEY, payload);\n    } catch {\n      // Non-fatal if storage is unavailable\n    }\n  }\n\n  private markAnnouncementSeen(): void {\n    // Clear badge only when explicitly dismissed\n    this.hasUnseenAnnouncement = false;\n    this.showAnnouncementPreview = false;\n\n    if (!this.announcementTimestamp) {\n      // If still loading, attempt once more after promise resolves; avoid infinite requeues\n      if (this.announcementPromise && !this.announcementLoaded) {\n        void this.announcementPromise\n          .then(() => this.markAnnouncementSeen())\n          .catch(() => undefined);\n      }\n      this.requestUpdate();\n      return;\n    }\n\n    this.persistAnnouncementTimestamp(this.announcementTimestamp);\n    this.requestUpdate();\n  }\n}\n\nexport function defineWebInspector(): void {\n  if (!customElements.get(WEB_INSPECTOR_TAG)) {\n    customElements.define(WEB_INSPECTOR_TAG, WebInspectorElement);\n  }\n}\n\ndefineWebInspector();\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    \"cpk-web-inspector\": WebInspectorElement;\n  }\n}\n"],"mappings":"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"}