@copilotkitnext/web-inspector 1.51.4-next.7 → 1.51.4-next.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts CHANGED
@@ -13,7 +13,14 @@ import {
13
13
  type CopilotKitCoreErrorCode,
14
14
  } from "@copilotkitnext/core";
15
15
  import type { AbstractAgent, AgentSubscriber } from "@ag-ui/client";
16
- import type { Anchor, ContextKey, ContextState, DockMode, Position, Size } from "./lib/types";
16
+ import type {
17
+ Anchor,
18
+ ContextKey,
19
+ ContextState,
20
+ DockMode,
21
+ Position,
22
+ Size,
23
+ } from "./lib/types";
17
24
  import {
18
25
  applyAnchorPosition as applyAnchorPositionHelper,
19
26
  centerContext as centerContextHelper,
@@ -147,14 +154,20 @@ export class WebInspectorElement extends LitElement {
147
154
  private coreUnsubscribe: (() => void) | null = null;
148
155
  private runtimeStatus: CopilotKitCoreRuntimeConnectionStatus | null = null;
149
156
  private coreProperties: Readonly<Record<string, unknown>> = {};
150
- private lastCoreError: { code: CopilotKitCoreErrorCode; message: string } | null = null;
157
+ private lastCoreError: {
158
+ code: CopilotKitCoreErrorCode;
159
+ message: string;
160
+ } | null = null;
151
161
  private agentSubscriptions: Map<string, () => void> = new Map();
152
162
  private agentEvents: Map<string, InspectorEvent[]> = new Map();
153
163
  private agentMessages: Map<string, InspectorMessage[]> = new Map();
154
164
  private agentStates: Map<string, SanitizedValue> = new Map();
155
165
  private flattenedEvents: InspectorEvent[] = [];
156
166
  private eventCounter = 0;
157
- private contextStore: Record<string, { description?: string; value: unknown }> = {};
167
+ private contextStore: Record<
168
+ string,
169
+ { description?: string; value: unknown }
170
+ > = {};
158
171
 
159
172
  private pointerId: number | null = null;
160
173
  private dragStart: Position | null = null;
@@ -301,7 +314,9 @@ export class WebInspectorElement extends LitElement {
301
314
  this.eventCounter = 0;
302
315
  }
303
316
 
304
- private processAgentsChanged(agents: Readonly<Record<string, AbstractAgent>>): void {
317
+ private processAgentsChanged(
318
+ agents: Readonly<Record<string, AbstractAgent>>,
319
+ ): void {
305
320
  const seenAgentIds = new Set<string>();
306
321
 
307
322
  for (const agent of Object.values(agents)) {
@@ -355,7 +370,12 @@ export class WebInspectorElement extends LitElement {
355
370
  }
356
371
 
357
372
  private tryAutoAttachCore(): void {
358
- if (this.attemptedAutoAttach || this._core || !this.autoAttachCore || typeof window === "undefined") {
373
+ if (
374
+ this.attemptedAutoAttach ||
375
+ this._core ||
376
+ !this.autoAttachCore ||
377
+ typeof window === "undefined"
378
+ ) {
359
379
  return;
360
380
  }
361
381
 
@@ -370,7 +390,8 @@ export class WebInspectorElement extends LitElement {
370
390
  ];
371
391
 
372
392
  const foundCore = globalCandidates.find(
373
- (candidate): candidate is CopilotKitCore => !!candidate && typeof candidate === "object",
393
+ (candidate): candidate is CopilotKitCore =>
394
+ !!candidate && typeof candidate === "object",
374
395
  );
375
396
 
376
397
  if (foundCore) {
@@ -401,19 +422,39 @@ export class WebInspectorElement extends LitElement {
401
422
  this.recordAgentEvent(agentId, "TEXT_MESSAGE_START", event);
402
423
  },
403
424
  onTextMessageContentEvent: ({ event, textMessageBuffer }) => {
404
- this.recordAgentEvent(agentId, "TEXT_MESSAGE_CONTENT", { event, textMessageBuffer });
425
+ this.recordAgentEvent(agentId, "TEXT_MESSAGE_CONTENT", {
426
+ event,
427
+ textMessageBuffer,
428
+ });
405
429
  },
406
430
  onTextMessageEndEvent: ({ event, textMessageBuffer }) => {
407
- this.recordAgentEvent(agentId, "TEXT_MESSAGE_END", { event, textMessageBuffer });
431
+ this.recordAgentEvent(agentId, "TEXT_MESSAGE_END", {
432
+ event,
433
+ textMessageBuffer,
434
+ });
408
435
  },
409
436
  onToolCallStartEvent: ({ event }) => {
410
437
  this.recordAgentEvent(agentId, "TOOL_CALL_START", event);
411
438
  },
412
- onToolCallArgsEvent: ({ event, toolCallBuffer, toolCallName, partialToolCallArgs }) => {
413
- this.recordAgentEvent(agentId, "TOOL_CALL_ARGS", { event, toolCallBuffer, toolCallName, partialToolCallArgs });
439
+ onToolCallArgsEvent: ({
440
+ event,
441
+ toolCallBuffer,
442
+ toolCallName,
443
+ partialToolCallArgs,
444
+ }) => {
445
+ this.recordAgentEvent(agentId, "TOOL_CALL_ARGS", {
446
+ event,
447
+ toolCallBuffer,
448
+ toolCallName,
449
+ partialToolCallArgs,
450
+ });
414
451
  },
415
452
  onToolCallEndEvent: ({ event, toolCallArgs, toolCallName }) => {
416
- this.recordAgentEvent(agentId, "TOOL_CALL_END", { event, toolCallArgs, toolCallName });
453
+ this.recordAgentEvent(agentId, "TOOL_CALL_END", {
454
+ event,
455
+ toolCallArgs,
456
+ toolCallName,
457
+ });
417
458
  },
418
459
  onToolCallResultEvent: ({ event }) => {
419
460
  this.recordAgentEvent(agentId, "TOOL_CALL_RESULT", event);
@@ -459,7 +500,11 @@ export class WebInspectorElement extends LitElement {
459
500
  }
460
501
  }
461
502
 
462
- private recordAgentEvent(agentId: string, type: InspectorAgentEventType, payload: unknown): void {
503
+ private recordAgentEvent(
504
+ agentId: string,
505
+ type: InspectorAgentEventType,
506
+ payload: unknown,
507
+ ): void {
463
508
  const eventId = `${agentId}:${++this.eventCounter}`;
464
509
  const normalizedPayload = this.normalizeEventPayload(type, payload);
465
510
  const event: InspectorEvent = {
@@ -471,10 +516,16 @@ export class WebInspectorElement extends LitElement {
471
516
  };
472
517
 
473
518
  const currentAgentEvents = this.agentEvents.get(agentId) ?? [];
474
- const nextAgentEvents = [event, ...currentAgentEvents].slice(0, MAX_AGENT_EVENTS);
519
+ const nextAgentEvents = [event, ...currentAgentEvents].slice(
520
+ 0,
521
+ MAX_AGENT_EVENTS,
522
+ );
475
523
  this.agentEvents.set(agentId, nextAgentEvents);
476
524
 
477
- this.flattenedEvents = [event, ...this.flattenedEvents].slice(0, MAX_TOTAL_EVENTS);
525
+ this.flattenedEvents = [event, ...this.flattenedEvents].slice(
526
+ 0,
527
+ MAX_TOTAL_EVENTS,
528
+ );
478
529
  this.refreshToolsSnapshot();
479
530
  this.requestUpdate();
480
531
  }
@@ -484,7 +535,9 @@ export class WebInspectorElement extends LitElement {
484
535
  return;
485
536
  }
486
537
 
487
- const messages = this.normalizeAgentMessages((agent as { messages?: unknown }).messages);
538
+ const messages = this.normalizeAgentMessages(
539
+ (agent as { messages?: unknown }).messages,
540
+ );
488
541
  if (messages) {
489
542
  this.agentMessages.set(agent.agentId, messages);
490
543
  } else {
@@ -520,7 +573,9 @@ export class WebInspectorElement extends LitElement {
520
573
 
521
574
  const optionsChanged =
522
575
  this.contextOptions.length !== nextOptions.length ||
523
- this.contextOptions.some((option, index) => option.key !== nextOptions[index]?.key);
576
+ this.contextOptions.some(
577
+ (option, index) => option.key !== nextOptions[index]?.key,
578
+ );
524
579
 
525
580
  if (optionsChanged) {
526
581
  this.contextOptions = nextOptions;
@@ -528,7 +583,8 @@ export class WebInspectorElement extends LitElement {
528
583
 
529
584
  const pendingContext = this.pendingSelectedContext;
530
585
  if (pendingContext) {
531
- const isPendingAvailable = pendingContext === "all-agents" || agentIds.has(pendingContext);
586
+ const isPendingAvailable =
587
+ pendingContext === "all-agents" || agentIds.has(pendingContext);
532
588
  if (isPendingAvailable) {
533
589
  if (this.selectedContext !== pendingContext) {
534
590
  this.selectedContext = pendingContext;
@@ -541,7 +597,9 @@ export class WebInspectorElement extends LitElement {
541
597
  }
542
598
  }
543
599
 
544
- const hasSelectedContext = nextOptions.some((option) => option.key === this.selectedContext);
600
+ const hasSelectedContext = nextOptions.some(
601
+ (option) => option.key === this.selectedContext,
602
+ );
545
603
 
546
604
  if (!hasSelectedContext && this.pendingSelectedContext === null) {
547
605
  // Auto-select "default" agent if it exists, otherwise first agent, otherwise "all-agents"
@@ -550,7 +608,9 @@ export class WebInspectorElement extends LitElement {
550
608
  if (agentIds.has("default")) {
551
609
  nextSelected = "default";
552
610
  } else if (agentIds.size > 0) {
553
- nextSelected = Array.from(agentIds).sort((a, b) => a.localeCompare(b))[0]!;
611
+ nextSelected = Array.from(agentIds).sort((a, b) =>
612
+ a.localeCompare(b),
613
+ )[0]!;
554
614
  }
555
615
 
556
616
  if (this.selectedContext !== nextSelected) {
@@ -573,7 +633,10 @@ export class WebInspectorElement extends LitElement {
573
633
  const query = this.eventFilterText.trim().toLowerCase();
574
634
 
575
635
  return events.filter((event) => {
576
- if (this.eventTypeFilter !== "all" && event.type !== this.eventTypeFilter) {
636
+ if (
637
+ this.eventTypeFilter !== "all" &&
638
+ event.type !== this.eventTypeFilter
639
+ ) {
577
640
  return false;
578
641
  }
579
642
 
@@ -581,7 +644,10 @@ export class WebInspectorElement extends LitElement {
581
644
  return true;
582
645
  }
583
646
 
584
- const payloadText = this.stringifyPayload(event.payload, false).toLowerCase();
647
+ const payloadText = this.stringifyPayload(
648
+ event.payload,
649
+ false,
650
+ ).toLowerCase();
585
651
  return (
586
652
  event.type.toLowerCase().includes(query) ||
587
653
  event.agentId.toLowerCase().includes(query) ||
@@ -604,7 +670,9 @@ export class WebInspectorElement extends LitElement {
604
670
  return stateEvent.payload;
605
671
  }
606
672
 
607
- private getLatestMessagesForAgent(agentId: string): InspectorMessage[] | null {
673
+ private getLatestMessagesForAgent(
674
+ agentId: string,
675
+ ): InspectorMessage[] | null {
608
676
  const messages = this.agentMessages.get(agentId);
609
677
  return messages ?? null;
610
678
  }
@@ -616,7 +684,12 @@ export class WebInspectorElement extends LitElement {
616
684
  }
617
685
 
618
686
  // Check most recent run-related event
619
- const runEvent = events.find((e) => e.type === "RUN_STARTED" || e.type === "RUN_FINISHED" || e.type === "RUN_ERROR");
687
+ const runEvent = events.find(
688
+ (e) =>
689
+ e.type === "RUN_STARTED" ||
690
+ e.type === "RUN_FINISHED" ||
691
+ e.type === "RUN_ERROR",
692
+ );
620
693
 
621
694
  if (!runEvent) {
622
695
  return "idle";
@@ -629,7 +702,7 @@ export class WebInspectorElement extends LitElement {
629
702
  if (runEvent.type === "RUN_STARTED") {
630
703
  // Check if there's a RUN_FINISHED after this
631
704
  const finishedAfter = events.find(
632
- (e) => e.type === "RUN_FINISHED" && e.timestamp > runEvent.timestamp
705
+ (e) => e.type === "RUN_FINISHED" && e.timestamp > runEvent.timestamp,
633
706
  );
634
707
  return finishedAfter ? "idle" : "running";
635
708
  }
@@ -637,13 +710,22 @@ export class WebInspectorElement extends LitElement {
637
710
  return "idle";
638
711
  }
639
712
 
640
- private getAgentStats(agentId: string): { totalEvents: number; lastActivity: number | null; messages: number; toolCalls: number; errors: number } {
713
+ private getAgentStats(agentId: string): {
714
+ totalEvents: number;
715
+ lastActivity: number | null;
716
+ messages: number;
717
+ toolCalls: number;
718
+ errors: number;
719
+ } {
641
720
  const events = this.agentEvents.get(agentId) ?? [];
642
721
 
643
722
  const messages = this.agentMessages.get(agentId);
644
723
 
645
724
  const toolCallCount = messages
646
- ? messages.reduce((count, message) => count + (message.toolCalls?.length ?? 0), 0)
725
+ ? messages.reduce(
726
+ (count, message) => count + (message.toolCalls?.length ?? 0),
727
+ 0,
728
+ )
647
729
  : events.filter((e) => e.type === "TOOL_CALL_END").length;
648
730
 
649
731
  const messageCount = messages?.length ?? 0;
@@ -665,17 +747,29 @@ export class WebInspectorElement extends LitElement {
665
747
  return html`
666
748
  <div class="mt-2 space-y-2">
667
749
  ${toolCalls.map((call, index) => {
668
- const functionName = call.function?.name ?? call.toolName ?? "Unknown function";
669
- const callId = typeof call?.id === "string" ? call.id : `tool-call-${index + 1}`;
670
- const argsString = this.formatToolCallArguments(call.function?.arguments);
750
+ const functionName =
751
+ call.function?.name ?? call.toolName ?? "Unknown function";
752
+ const callId =
753
+ typeof call?.id === "string" ? call.id : `tool-call-${index + 1}`;
754
+ const argsString = this.formatToolCallArguments(
755
+ call.function?.arguments,
756
+ );
671
757
  return html`
672
- <div class="rounded-md border border-gray-200 bg-gray-50 p-3 text-xs text-gray-700">
673
- <div class="flex flex-wrap items-center justify-between gap-1 font-medium text-gray-900">
758
+ <div
759
+ class="rounded-md border border-gray-200 bg-gray-50 p-3 text-xs text-gray-700"
760
+ >
761
+ <div
762
+ class="flex flex-wrap items-center justify-between gap-1 font-medium text-gray-900"
763
+ >
674
764
  <span>${functionName}</span>
675
765
  <span class="text-[10px] text-gray-500">ID: ${callId}</span>
676
766
  </div>
677
767
  ${argsString
678
- ? html`<pre class="mt-2 overflow-auto rounded bg-white p-2 text-[11px] leading-relaxed text-gray-800">${argsString}</pre>`
768
+ ? html`<pre
769
+ class="mt-2 overflow-auto rounded bg-white p-2 text-[11px] leading-relaxed text-gray-800"
770
+ >
771
+ ${argsString}</pre
772
+ >`
679
773
  : nothing}
680
774
  </div>
681
775
  `;
@@ -685,11 +779,11 @@ export class WebInspectorElement extends LitElement {
685
779
  }
686
780
 
687
781
  private formatToolCallArguments(args: unknown): string | null {
688
- if (args === undefined || args === null || args === '') {
782
+ if (args === undefined || args === null || args === "") {
689
783
  return null;
690
784
  }
691
785
 
692
- if (typeof args === 'string') {
786
+ if (typeof args === "string") {
693
787
  try {
694
788
  const parsed = JSON.parse(args);
695
789
  return JSON.stringify(parsed, null, 2);
@@ -698,7 +792,7 @@ export class WebInspectorElement extends LitElement {
698
792
  }
699
793
  }
700
794
 
701
- if (typeof args === 'object') {
795
+ if (typeof args === "object") {
702
796
  try {
703
797
  return JSON.stringify(args, null, 2);
704
798
  } catch {
@@ -718,13 +812,13 @@ export class WebInspectorElement extends LitElement {
718
812
  return state.length > 0;
719
813
  }
720
814
 
721
- if (typeof state === 'object') {
815
+ if (typeof state === "object") {
722
816
  return Object.keys(state as Record<string, unknown>).length > 0;
723
817
  }
724
818
 
725
- if (typeof state === 'string') {
819
+ if (typeof state === "string") {
726
820
  const trimmed = state.trim();
727
- return trimmed.length > 0 && trimmed !== '{}';
821
+ return trimmed.length > 0 && trimmed !== "{}";
728
822
  }
729
823
 
730
824
  return true;
@@ -732,13 +826,13 @@ export class WebInspectorElement extends LitElement {
732
826
 
733
827
  private formatStateForDisplay(state: unknown): string {
734
828
  if (state === null || state === undefined) {
735
- return '';
829
+ return "";
736
830
  }
737
831
 
738
- if (typeof state === 'string') {
832
+ if (typeof state === "string") {
739
833
  const trimmed = state.trim();
740
834
  if (trimmed.length === 0) {
741
- return '';
835
+ return "";
742
836
  }
743
837
  try {
744
838
  const parsed = JSON.parse(trimmed);
@@ -748,7 +842,7 @@ export class WebInspectorElement extends LitElement {
748
842
  }
749
843
  }
750
844
 
751
- if (typeof state === 'object') {
845
+ if (typeof state === "object") {
752
846
  try {
753
847
  return JSON.stringify(state, null, 2);
754
848
  } catch {
@@ -760,7 +854,8 @@ export class WebInspectorElement extends LitElement {
760
854
  }
761
855
 
762
856
  private getEventBadgeClasses(type: string): string {
763
- const base = "font-mono text-[10px] font-medium inline-flex items-center rounded-sm px-1.5 py-0.5 border";
857
+ const base =
858
+ "font-mono text-[10px] font-medium inline-flex items-center rounded-sm px-1.5 py-0.5 border";
764
859
 
765
860
  if (type.startsWith("RUN_")) {
766
861
  return `${base} bg-blue-50 text-blue-700 border-blue-200`;
@@ -856,7 +951,9 @@ export class WebInspectorElement extends LitElement {
856
951
  }
857
952
 
858
953
  .inspector-window[data-transitioning="true"] {
859
- transition: width 300ms ease, height 300ms ease;
954
+ transition:
955
+ width 300ms ease,
956
+ height 300ms ease;
860
957
  }
861
958
 
862
959
  .inspector-window[data-docked="true"] {
@@ -901,7 +998,9 @@ export class WebInspectorElement extends LitElement {
901
998
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
902
999
  opacity: 0;
903
1000
  pointer-events: none;
904
- transition: opacity 120ms ease, transform 120ms ease;
1001
+ transition:
1002
+ opacity 120ms ease,
1003
+ transform 120ms ease;
905
1004
  z-index: 4000;
906
1005
  }
907
1006
 
@@ -973,7 +1072,9 @@ export class WebInspectorElement extends LitElement {
973
1072
  border-radius: 8px;
974
1073
  border: 1px solid rgba(148, 163, 184, 0.5);
975
1074
  background: rgba(248, 250, 252, 0.9);
976
- transition: background 120ms ease, color 120ms ease;
1075
+ transition:
1076
+ background 120ms ease,
1077
+ color 120ms ease;
977
1078
  }
978
1079
 
979
1080
  .announcement-dismiss:hover {
@@ -1033,7 +1134,10 @@ export class WebInspectorElement extends LitElement {
1033
1134
  super.connectedCallback();
1034
1135
  if (typeof window !== "undefined") {
1035
1136
  window.addEventListener("resize", this.handleResize);
1036
- window.addEventListener("pointerdown", this.handleGlobalPointerDown as EventListener);
1137
+ window.addEventListener(
1138
+ "pointerdown",
1139
+ this.handleGlobalPointerDown as EventListener,
1140
+ );
1037
1141
 
1038
1142
  // Load state early (before first render) so menu selection is correct
1039
1143
  this.hydrateStateFromStorageEarly();
@@ -1046,7 +1150,10 @@ export class WebInspectorElement extends LitElement {
1046
1150
  super.disconnectedCallback();
1047
1151
  if (typeof window !== "undefined") {
1048
1152
  window.removeEventListener("resize", this.handleResize);
1049
- window.removeEventListener("pointerdown", this.handleGlobalPointerDown as EventListener);
1153
+ window.removeEventListener(
1154
+ "pointerdown",
1155
+ this.handleGlobalPointerDown as EventListener,
1156
+ );
1050
1157
  }
1051
1158
  this.removeDockStyles(); // Clean up any docking styles
1052
1159
  this.detachFromCore();
@@ -1073,13 +1180,13 @@ export class WebInspectorElement extends LitElement {
1073
1180
  this.hydrateStateFromStorage();
1074
1181
 
1075
1182
  // Apply docking styles if open and docked (skip transition on initial load)
1076
- if (this.isOpen && this.dockMode !== 'floating') {
1183
+ if (this.isOpen && this.dockMode !== "floating") {
1077
1184
  this.applyDockStyles(true);
1078
1185
  }
1079
1186
 
1080
1187
  this.applyAnchorPosition("button");
1081
1188
 
1082
- if (this.dockMode === 'floating') {
1189
+ if (this.dockMode === "floating") {
1083
1190
  if (this.hasCustomPosition.window) {
1084
1191
  this.applyAnchorPosition("window");
1085
1192
  } else {
@@ -1136,7 +1243,9 @@ export class WebInspectorElement extends LitElement {
1136
1243
  type="button"
1137
1244
  aria-label="Web Inspector"
1138
1245
  data-drag-context="button"
1139
- data-dragging=${this.isDragging && this.pointerContext === "button" ? "true" : "false"}
1246
+ data-dragging=${this.isDragging && this.pointerContext === "button"
1247
+ ? "true"
1248
+ : "false"}
1140
1249
  @pointerdown=${this.handlePointerDown}
1141
1250
  @pointermove=${this.handlePointerMove}
1142
1251
  @pointerup=${this.handlePointerUp}
@@ -1144,15 +1253,20 @@ export class WebInspectorElement extends LitElement {
1144
1253
  @click=${this.handleButtonClick}
1145
1254
  >
1146
1255
  ${this.renderAnnouncementPreview()}
1147
- <img src=${inspectorLogoIconUrl} alt="Inspector logo" class="h-5 w-auto" loading="lazy" />
1256
+ <img
1257
+ src=${inspectorLogoIconUrl}
1258
+ alt="Inspector logo"
1259
+ class="h-5 w-auto"
1260
+ loading="lazy"
1261
+ />
1148
1262
  </button>
1149
1263
  `;
1150
1264
  }
1151
1265
 
1152
1266
  private renderWindow() {
1153
1267
  const windowState = this.contextState.window;
1154
- const isDocked = this.dockMode !== 'floating';
1155
- const isTransitioning = this.hasAttribute('data-transitioning');
1268
+ const isDocked = this.dockMode !== "floating";
1269
+ const isTransitioning = this.hasAttribute("data-transitioning");
1156
1270
 
1157
1271
  const windowStyles = isDocked
1158
1272
  ? this.getDockedWindowStyles()
@@ -1164,12 +1278,16 @@ export class WebInspectorElement extends LitElement {
1164
1278
  };
1165
1279
 
1166
1280
  const hasContextDropdown = this.contextOptions.length > 0;
1167
- const contextDropdown = hasContextDropdown ? this.renderContextDropdown() : nothing;
1281
+ const contextDropdown = hasContextDropdown
1282
+ ? this.renderContextDropdown()
1283
+ : nothing;
1168
1284
  const coreStatus = this.getCoreStatusSummary();
1169
1285
  const agentSelector = hasContextDropdown
1170
1286
  ? contextDropdown
1171
1287
  : html`
1172
- <div class="flex items-center gap-2 rounded-md border border-dashed border-gray-200 px-2 py-1 text-xs text-gray-400">
1288
+ <div
1289
+ class="flex items-center gap-2 rounded-md border border-dashed border-gray-200 px-2 py-1 text-xs text-gray-400"
1290
+ >
1173
1291
  <span>${this.renderIcon("Bot")}</span>
1174
1292
  <span class="truncate">No agents available</span>
1175
1293
  </div>
@@ -1195,9 +1313,15 @@ export class WebInspectorElement extends LitElement {
1195
1313
  ></div>
1196
1314
  `
1197
1315
  : nothing}
1198
- <div class="flex flex-1 flex-col overflow-hidden bg-white text-gray-800">
1316
+ <div
1317
+ class="flex flex-1 flex-col overflow-hidden bg-white text-gray-800"
1318
+ >
1199
1319
  <div
1200
- class="drag-handle relative z-30 flex flex-col border-b border-gray-200 bg-white/95 backdrop-blur-sm ${isDocked ? '' : (this.isDragging && this.pointerContext === 'window' ? 'cursor-grabbing' : 'cursor-grab')}"
1320
+ class="drag-handle relative z-30 flex flex-col border-b border-gray-200 bg-white/95 backdrop-blur-sm ${isDocked
1321
+ ? ""
1322
+ : this.isDragging && this.pointerContext === "window"
1323
+ ? "cursor-grabbing"
1324
+ : "cursor-grab"}"
1201
1325
  data-drag-context="window"
1202
1326
  @pointerdown=${isDocked ? undefined : this.handlePointerDown}
1203
1327
  @pointermove=${isDocked ? undefined : this.handlePointerMove}
@@ -1206,12 +1330,15 @@ export class WebInspectorElement extends LitElement {
1206
1330
  >
1207
1331
  <div class="flex flex-wrap items-center gap-3 px-4 py-3">
1208
1332
  <div class="flex items-center min-w-0">
1209
- <img src=${inspectorLogoUrl} alt="Inspector logo" class="h-6 w-auto" loading="lazy" />
1333
+ <img
1334
+ src=${inspectorLogoUrl}
1335
+ alt="Inspector logo"
1336
+ class="h-6 w-auto"
1337
+ loading="lazy"
1338
+ />
1210
1339
  </div>
1211
1340
  <div class="ml-auto flex min-w-0 items-center gap-2">
1212
- <div class="min-w-[160px] max-w-xs">
1213
- ${agentSelector}
1214
- </div>
1341
+ <div class="min-w-[160px] max-w-xs">${agentSelector}</div>
1215
1342
  <div class="flex items-center gap-1">
1216
1343
  ${this.renderDockControls()}
1217
1344
  <button
@@ -1226,12 +1353,16 @@ export class WebInspectorElement extends LitElement {
1226
1353
  </div>
1227
1354
  </div>
1228
1355
  </div>
1229
- <div class="flex flex-wrap items-center gap-2 border-t border-gray-100 px-3 py-2 text-xs">
1356
+ <div
1357
+ class="flex flex-wrap items-center gap-2 border-t border-gray-100 px-3 py-2 text-xs"
1358
+ >
1230
1359
  ${this.menuItems.map(({ key, label, icon }) => {
1231
1360
  const isSelected = this.selectedMenu === key;
1232
1361
  const tabClasses = [
1233
1362
  "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",
1234
- isSelected ? "bg-gray-900 text-white shadow-sm" : "text-gray-600 hover:bg-gray-100 hover:text-gray-900",
1363
+ isSelected
1364
+ ? "bg-gray-900 text-white shadow-sm"
1365
+ : "text-gray-600 hover:bg-gray-100 hover:text-gray-900",
1235
1366
  ].join(" ");
1236
1367
 
1237
1368
  return html`
@@ -1241,7 +1372,9 @@ export class WebInspectorElement extends LitElement {
1241
1372
  aria-pressed=${isSelected}
1242
1373
  @click=${() => this.handleMenuSelect(key)}
1243
1374
  >
1244
- <span class="text-gray-400 ${isSelected ? 'text-white' : ''}">
1375
+ <span
1376
+ class="text-gray-400 ${isSelected ? "text-white" : ""}"
1377
+ >
1245
1378
  ${this.renderIcon(icon)}
1246
1379
  </span>
1247
1380
  <span>${label}</span>
@@ -1250,27 +1383,30 @@ export class WebInspectorElement extends LitElement {
1250
1383
  })}
1251
1384
  </div>
1252
1385
  </div>
1253
- <div class="flex flex-1 flex-col overflow-hidden">
1254
- <div class="flex-1 overflow-auto">
1255
- ${this.renderAnnouncementPanel()}
1256
- ${this.renderCoreWarningBanner()}
1257
- ${this.renderMainContent()}
1258
- <slot></slot>
1259
- </div>
1260
- <div class="border-t border-gray-200 bg-gray-50 px-4 py-2">
1261
- <div
1262
- class="flex items-center gap-2 rounded-md px-3 py-2 text-xs ${coreStatus.tone} w-full overflow-hidden my-1"
1263
- title=${coreStatus.description}
1386
+ <div class="flex flex-1 flex-col overflow-hidden">
1387
+ <div class="flex-1 overflow-auto">
1388
+ ${this.renderAnnouncementPanel()}
1389
+ ${this.renderCoreWarningBanner()} ${this.renderMainContent()}
1390
+ <slot></slot>
1391
+ </div>
1392
+ <div class="border-t border-gray-200 bg-gray-50 px-4 py-2">
1393
+ <div
1394
+ class="flex items-center gap-2 rounded-md px-3 py-2 text-xs ${coreStatus.tone} w-full overflow-hidden my-1"
1395
+ title=${coreStatus.description}
1396
+ >
1397
+ <span
1398
+ class="flex h-6 w-6 items-center justify-center rounded bg-white/60"
1399
+ >
1400
+ ${this.renderIcon("Activity")}
1401
+ </span>
1402
+ <span class="font-medium">${coreStatus.label}</span>
1403
+ <span class="truncate text-[11px] opacity-80"
1404
+ >${coreStatus.description}</span
1264
1405
  >
1265
- <span class="flex h-6 w-6 items-center justify-center rounded bg-white/60">
1266
- ${this.renderIcon("Activity")}
1267
- </span>
1268
- <span class="font-medium">${coreStatus.label}</span>
1269
- <span class="truncate text-[11px] opacity-80">${coreStatus.description}</span>
1270
- </div>
1271
1406
  </div>
1272
1407
  </div>
1273
1408
  </div>
1409
+ </div>
1274
1410
  <div
1275
1411
  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"
1276
1412
  role="presentation"
@@ -1318,7 +1454,9 @@ export class WebInspectorElement extends LitElement {
1318
1454
 
1319
1455
  // Restore selected menu
1320
1456
  if (typeof persisted.selectedMenu === "string") {
1321
- const validMenu = this.menuItems.find((item) => item.key === persisted.selectedMenu);
1457
+ const validMenu = this.menuItems.find(
1458
+ (item) => item.key === persisted.selectedMenu,
1459
+ );
1322
1460
  if (validMenu) {
1323
1461
  this.selectedMenu = validMenu.key;
1324
1462
  }
@@ -1368,7 +1506,9 @@ export class WebInspectorElement extends LitElement {
1368
1506
 
1369
1507
  if (isValidSize(persistedWindow.size)) {
1370
1508
  // Now clampWindowSize will use the correct minimum based on dockMode
1371
- this.contextState.window.size = this.clampWindowSize(persistedWindow.size);
1509
+ this.contextState.window.size = this.clampWindowSize(
1510
+ persistedWindow.size,
1511
+ );
1372
1512
  }
1373
1513
 
1374
1514
  if (typeof persistedWindow.hasCustomPosition === "boolean") {
@@ -1388,7 +1528,7 @@ export class WebInspectorElement extends LitElement {
1388
1528
 
1389
1529
  private handlePointerDown = (event: PointerEvent) => {
1390
1530
  // Don't allow dragging when docked
1391
- if (this.dockMode !== 'floating' && this.isOpen) {
1531
+ if (this.dockMode !== "floating" && this.isOpen) {
1392
1532
  return;
1393
1533
  }
1394
1534
 
@@ -1421,11 +1561,18 @@ export class WebInspectorElement extends LitElement {
1421
1561
  };
1422
1562
 
1423
1563
  private handlePointerMove = (event: PointerEvent) => {
1424
- if (this.pointerId !== event.pointerId || !this.dragStart || !this.pointerContext) {
1564
+ if (
1565
+ this.pointerId !== event.pointerId ||
1566
+ !this.dragStart ||
1567
+ !this.pointerContext
1568
+ ) {
1425
1569
  return;
1426
1570
  }
1427
1571
 
1428
- const distance = Math.hypot(event.clientX - this.dragStart.x, event.clientY - this.dragStart.y);
1572
+ const distance = Math.hypot(
1573
+ event.clientX - this.dragStart.x,
1574
+ event.clientY - this.dragStart.y,
1575
+ );
1429
1576
  if (!this.isDragging && distance < DRAG_THRESHOLD) {
1430
1577
  return;
1431
1578
  }
@@ -1471,7 +1618,11 @@ export class WebInspectorElement extends LitElement {
1471
1618
  this.ignoreNextButtonClick = true;
1472
1619
  }
1473
1620
  }
1474
- } else if (context === "button" && !this.isOpen && !this.draggedDuringInteraction) {
1621
+ } else if (
1622
+ context === "button" &&
1623
+ !this.isOpen &&
1624
+ !this.draggedDuringInteraction
1625
+ ) {
1475
1626
  this.openInspector();
1476
1627
  }
1477
1628
 
@@ -1529,8 +1680,8 @@ export class WebInspectorElement extends LitElement {
1529
1680
  this.resizeInitialSize = { ...this.contextState.window.size };
1530
1681
 
1531
1682
  // Remove transition from body during resize to prevent lag
1532
- if (document.body && this.dockMode !== 'floating') {
1533
- document.body.style.transition = '';
1683
+ if (document.body && this.dockMode !== "floating") {
1684
+ document.body.style.transition = "";
1534
1685
  }
1535
1686
 
1536
1687
  const target = event.currentTarget as HTMLElement | null;
@@ -1538,7 +1689,12 @@ export class WebInspectorElement extends LitElement {
1538
1689
  };
1539
1690
 
1540
1691
  private handleResizePointerMove = (event: PointerEvent) => {
1541
- if (!this.isResizing || this.resizePointerId !== event.pointerId || !this.resizeStart || !this.resizeInitialSize) {
1692
+ if (
1693
+ !this.isResizing ||
1694
+ this.resizePointerId !== event.pointerId ||
1695
+ !this.resizeStart ||
1696
+ !this.resizeInitialSize
1697
+ ) {
1542
1698
  return;
1543
1699
  }
1544
1700
 
@@ -1549,7 +1705,7 @@ export class WebInspectorElement extends LitElement {
1549
1705
  const state = this.contextState.window;
1550
1706
 
1551
1707
  // For docked states, only resize in the appropriate dimension
1552
- if (this.dockMode === 'docked-left') {
1708
+ if (this.dockMode === "docked-left") {
1553
1709
  // Only resize width for left dock
1554
1710
  state.size = this.clampWindowSize({
1555
1711
  width: this.resizeInitialSize.width + deltaX,
@@ -1584,7 +1740,7 @@ export class WebInspectorElement extends LitElement {
1584
1740
  }
1585
1741
 
1586
1742
  // Only update anchor position for floating mode
1587
- if (this.dockMode === 'floating') {
1743
+ if (this.dockMode === "floating") {
1588
1744
  this.updateAnchorFromPosition("window");
1589
1745
  this.applyAnchorPosition("window");
1590
1746
  }
@@ -1605,7 +1761,7 @@ export class WebInspectorElement extends LitElement {
1605
1761
  }
1606
1762
 
1607
1763
  // Only update anchor position for floating mode
1608
- if (this.dockMode === 'floating') {
1764
+ if (this.dockMode === "floating") {
1609
1765
  this.updateAnchorFromPosition("window");
1610
1766
  this.applyAnchorPosition("window");
1611
1767
  }
@@ -1630,12 +1786,16 @@ export class WebInspectorElement extends LitElement {
1630
1786
  };
1631
1787
 
1632
1788
  private measureContext(context: ContextKey): void {
1633
- const selector = context === "window" ? ".inspector-window" : ".console-button";
1634
- const element = this.renderRoot?.querySelector(selector) as HTMLElement | null;
1789
+ const selector =
1790
+ context === "window" ? ".inspector-window" : ".console-button";
1791
+ const element = this.renderRoot?.querySelector(
1792
+ selector,
1793
+ ) as HTMLElement | null;
1635
1794
  if (!element) {
1636
1795
  return;
1637
1796
  }
1638
- const fallback = context === "window" ? DEFAULT_WINDOW_SIZE : DEFAULT_BUTTON_SIZE;
1797
+ const fallback =
1798
+ context === "window" ? DEFAULT_WINDOW_SIZE : DEFAULT_BUTTON_SIZE;
1639
1799
  updateSizeFromElement(this.contextState[context], element, fallback);
1640
1800
  }
1641
1801
 
@@ -1667,18 +1827,30 @@ export class WebInspectorElement extends LitElement {
1667
1827
 
1668
1828
  const viewport = this.getViewportSize();
1669
1829
  keepPositionWithinViewport(this.contextState.window, viewport, EDGE_MARGIN);
1670
- updateAnchorFromPositionHelper(this.contextState.window, viewport, EDGE_MARGIN);
1830
+ updateAnchorFromPositionHelper(
1831
+ this.contextState.window,
1832
+ viewport,
1833
+ EDGE_MARGIN,
1834
+ );
1671
1835
  this.updateHostTransform("window");
1672
1836
  this.persistState();
1673
1837
  }
1674
1838
 
1675
- private constrainToViewport(position: Position, context: ContextKey): Position {
1839
+ private constrainToViewport(
1840
+ position: Position,
1841
+ context: ContextKey,
1842
+ ): Position {
1676
1843
  if (typeof window === "undefined") {
1677
1844
  return position;
1678
1845
  }
1679
1846
 
1680
1847
  const viewport = this.getViewportSize();
1681
- return constrainToViewport(this.contextState[context], position, viewport, EDGE_MARGIN);
1848
+ return constrainToViewport(
1849
+ this.contextState[context],
1850
+ position,
1851
+ viewport,
1852
+ EDGE_MARGIN,
1853
+ );
1682
1854
  }
1683
1855
 
1684
1856
  private keepPositionWithinViewport(context: ContextKey): void {
@@ -1687,7 +1859,11 @@ export class WebInspectorElement extends LitElement {
1687
1859
  }
1688
1860
 
1689
1861
  const viewport = this.getViewportSize();
1690
- keepPositionWithinViewport(this.contextState[context], viewport, EDGE_MARGIN);
1862
+ keepPositionWithinViewport(
1863
+ this.contextState[context],
1864
+ viewport,
1865
+ EDGE_MARGIN,
1866
+ );
1691
1867
  }
1692
1868
 
1693
1869
  private getViewportSize(): Size {
@@ -1725,7 +1901,10 @@ export class WebInspectorElement extends LitElement {
1725
1901
 
1726
1902
  private clampWindowSize(size: Size): Size {
1727
1903
  // Use smaller minimum width when docked left
1728
- const minWidth = this.dockMode === 'docked-left' ? MIN_WINDOW_WIDTH_DOCKED_LEFT : MIN_WINDOW_WIDTH;
1904
+ const minWidth =
1905
+ this.dockMode === "docked-left"
1906
+ ? MIN_WINDOW_WIDTH_DOCKED_LEFT
1907
+ : MIN_WINDOW_WIDTH;
1729
1908
 
1730
1909
  if (typeof window === "undefined") {
1731
1910
  return {
@@ -1735,7 +1914,13 @@ export class WebInspectorElement extends LitElement {
1735
1914
  }
1736
1915
 
1737
1916
  const viewport = this.getViewportSize();
1738
- return clampSizeToViewport(size, viewport, EDGE_MARGIN, minWidth, MIN_WINDOW_HEIGHT);
1917
+ return clampSizeToViewport(
1918
+ size,
1919
+ viewport,
1920
+ EDGE_MARGIN,
1921
+ minWidth,
1922
+ MIN_WINDOW_HEIGHT,
1923
+ );
1739
1924
  }
1740
1925
 
1741
1926
  private setDockMode(mode: DockMode): void {
@@ -1751,9 +1936,9 @@ export class WebInspectorElement extends LitElement {
1751
1936
 
1752
1937
  this.dockMode = mode;
1753
1938
 
1754
- if (mode !== 'floating') {
1939
+ if (mode !== "floating") {
1755
1940
  // For docking, set the target size immediately so body margins are correct
1756
- if (mode === 'docked-left') {
1941
+ if (mode === "docked-left") {
1757
1942
  this.contextState.window.size.width = DOCKED_LEFT_WIDTH;
1758
1943
  }
1759
1944
 
@@ -1762,29 +1947,29 @@ export class WebInspectorElement extends LitElement {
1762
1947
  } else {
1763
1948
  // When floating, set size first then center
1764
1949
  this.contextState.window.size = { ...DEFAULT_WINDOW_SIZE };
1765
- this.centerContext('window');
1950
+ this.centerContext("window");
1766
1951
  }
1767
1952
 
1768
1953
  this.persistState();
1769
1954
  this.requestUpdate();
1770
- this.updateHostTransform('window');
1955
+ this.updateHostTransform("window");
1771
1956
  }
1772
1957
 
1773
1958
  private startHostTransition(duration = 300): void {
1774
- this.setAttribute('data-transitioning', 'true');
1959
+ this.setAttribute("data-transitioning", "true");
1775
1960
 
1776
1961
  if (this.transitionTimeoutId !== null) {
1777
1962
  clearTimeout(this.transitionTimeoutId);
1778
1963
  }
1779
1964
 
1780
1965
  this.transitionTimeoutId = setTimeout(() => {
1781
- this.removeAttribute('data-transitioning');
1966
+ this.removeAttribute("data-transitioning");
1782
1967
  this.transitionTimeoutId = null;
1783
1968
  }, duration);
1784
1969
  }
1785
1970
 
1786
1971
  private applyDockStyles(skipTransition = false): void {
1787
- if (typeof document === 'undefined' || !document.body) {
1972
+ if (typeof document === "undefined" || !document.body) {
1788
1973
  return;
1789
1974
  }
1790
1975
 
@@ -1797,11 +1982,11 @@ export class WebInspectorElement extends LitElement {
1797
1982
 
1798
1983
  // Apply transition to body for smooth animation (only when docking, not during resize or initial load)
1799
1984
  if (!this.isResizing && !skipTransition) {
1800
- document.body.style.transition = 'margin 300ms ease';
1985
+ document.body.style.transition = "margin 300ms ease";
1801
1986
  }
1802
1987
 
1803
1988
  // Apply body margins with the actual window sizes
1804
- if (this.dockMode === 'docked-left') {
1989
+ if (this.dockMode === "docked-left") {
1805
1990
  document.body.style.marginLeft = `${this.contextState.window.size.width}px`;
1806
1991
  }
1807
1992
 
@@ -1809,20 +1994,20 @@ export class WebInspectorElement extends LitElement {
1809
1994
  if (!this.isResizing && !skipTransition) {
1810
1995
  setTimeout(() => {
1811
1996
  if (document.body) {
1812
- document.body.style.transition = '';
1997
+ document.body.style.transition = "";
1813
1998
  }
1814
1999
  }, 300);
1815
2000
  }
1816
2001
  }
1817
2002
 
1818
2003
  private removeDockStyles(): void {
1819
- if (typeof document === 'undefined' || !document.body) {
2004
+ if (typeof document === "undefined" || !document.body) {
1820
2005
  return;
1821
2006
  }
1822
2007
 
1823
2008
  // Only add transition if not resizing
1824
2009
  if (!this.isResizing) {
1825
- document.body.style.transition = 'margin 300ms ease';
2010
+ document.body.style.transition = "margin 300ms ease";
1826
2011
  }
1827
2012
 
1828
2013
  // Restore original margins if saved
@@ -1832,14 +2017,14 @@ export class WebInspectorElement extends LitElement {
1832
2017
  this.previousBodyMargins = null;
1833
2018
  } else {
1834
2019
  // Reset to default if no previous values
1835
- document.body.style.marginLeft = '';
1836
- document.body.style.marginBottom = '';
2020
+ document.body.style.marginLeft = "";
2021
+ document.body.style.marginBottom = "";
1837
2022
  }
1838
2023
 
1839
2024
  // Clean up transition after animation completes
1840
2025
  setTimeout(() => {
1841
2026
  if (document.body) {
1842
- document.body.style.transition = '';
2027
+ document.body.style.transition = "";
1843
2028
  }
1844
2029
  }, 300);
1845
2030
  }
@@ -1850,7 +2035,7 @@ export class WebInspectorElement extends LitElement {
1850
2035
  }
1851
2036
 
1852
2037
  // For docked states, CSS handles positioning with fixed positioning
1853
- if (this.isOpen && this.dockMode === 'docked-left') {
2038
+ if (this.isOpen && this.dockMode === "docked-left") {
1854
2039
  this.style.transform = `translate3d(0, 0, 0)`;
1855
2040
  } else {
1856
2041
  const { position } = this.contextState[context];
@@ -1870,7 +2055,11 @@ export class WebInspectorElement extends LitElement {
1870
2055
  return;
1871
2056
  }
1872
2057
  const viewport = this.getViewportSize();
1873
- updateAnchorFromPositionHelper(this.contextState[context], viewport, EDGE_MARGIN);
2058
+ updateAnchorFromPositionHelper(
2059
+ this.contextState[context],
2060
+ viewport,
2061
+ EDGE_MARGIN,
2062
+ );
1874
2063
  }
1875
2064
 
1876
2065
  private snapButtonToCorner(): void {
@@ -1885,8 +2074,10 @@ export class WebInspectorElement extends LitElement {
1885
2074
  const centerX = state.position.x + state.size.width / 2;
1886
2075
  const centerY = state.position.y + state.size.height / 2;
1887
2076
 
1888
- const horizontal: Anchor['horizontal'] = centerX < viewport.width / 2 ? 'left' : 'right';
1889
- const vertical: Anchor['vertical'] = centerY < viewport.height / 2 ? 'top' : 'bottom';
2077
+ const horizontal: Anchor["horizontal"] =
2078
+ centerX < viewport.width / 2 ? "left" : "right";
2079
+ const vertical: Anchor["vertical"] =
2080
+ centerY < viewport.height / 2 ? "top" : "bottom";
1890
2081
 
1891
2082
  // Set anchor to nearest corner
1892
2083
  state.anchor = { horizontal, vertical };
@@ -1896,7 +2087,7 @@ export class WebInspectorElement extends LitElement {
1896
2087
 
1897
2088
  // Apply the anchor position to snap to corner
1898
2089
  this.startHostTransition();
1899
- this.applyAnchorPosition('button');
2090
+ this.applyAnchorPosition("button");
1900
2091
  }
1901
2092
 
1902
2093
  private applyAnchorPosition(context: ContextKey): void {
@@ -1904,7 +2095,11 @@ export class WebInspectorElement extends LitElement {
1904
2095
  return;
1905
2096
  }
1906
2097
  const viewport = this.getViewportSize();
1907
- applyAnchorPositionHelper(this.contextState[context], viewport, EDGE_MARGIN);
2098
+ applyAnchorPositionHelper(
2099
+ this.contextState[context],
2100
+ viewport,
2101
+ EDGE_MARGIN,
2102
+ );
1908
2103
  this.updateHostTransform(context);
1909
2104
  this.persistState();
1910
2105
  }
@@ -1937,7 +2132,7 @@ export class WebInspectorElement extends LitElement {
1937
2132
  this.persistState(); // Save the open state
1938
2133
 
1939
2134
  // Apply docking styles if in docked mode
1940
- if (this.dockMode !== 'floating') {
2135
+ if (this.dockMode !== "floating") {
1941
2136
  this.applyDockStyles();
1942
2137
  }
1943
2138
 
@@ -1945,7 +2140,7 @@ export class WebInspectorElement extends LitElement {
1945
2140
  this.requestUpdate();
1946
2141
  void this.updateComplete.then(() => {
1947
2142
  this.measureContext("window");
1948
- if (this.dockMode === 'floating') {
2143
+ if (this.dockMode === "floating") {
1949
2144
  if (this.hasCustomPosition.window) {
1950
2145
  this.applyAnchorPosition("window");
1951
2146
  } else {
@@ -1955,7 +2150,6 @@ export class WebInspectorElement extends LitElement {
1955
2150
  // Update transform for docked position
1956
2151
  this.updateHostTransform("window");
1957
2152
  }
1958
-
1959
2153
  });
1960
2154
  }
1961
2155
 
@@ -1967,7 +2161,7 @@ export class WebInspectorElement extends LitElement {
1967
2161
  this.isOpen = false;
1968
2162
 
1969
2163
  // Remove docking styles when closing
1970
- if (this.dockMode !== 'floating') {
2164
+ if (this.dockMode !== "floating") {
1971
2165
  this.removeDockStyles();
1972
2166
  }
1973
2167
 
@@ -2005,7 +2199,7 @@ export class WebInspectorElement extends LitElement {
2005
2199
  }
2006
2200
 
2007
2201
  private renderDockControls() {
2008
- if (this.dockMode === 'floating') {
2202
+ if (this.dockMode === "floating") {
2009
2203
  // Show dock left button
2010
2204
  return html`
2011
2205
  <button
@@ -2013,7 +2207,7 @@ export class WebInspectorElement extends LitElement {
2013
2207
  type="button"
2014
2208
  aria-label="Dock to left"
2015
2209
  title="Dock Left"
2016
- @click=${() => this.handleDockClick('docked-left')}
2210
+ @click=${() => this.handleDockClick("docked-left")}
2017
2211
  >
2018
2212
  ${this.renderIcon("PanelLeft")}
2019
2213
  </button>
@@ -2026,7 +2220,7 @@ export class WebInspectorElement extends LitElement {
2026
2220
  type="button"
2027
2221
  aria-label="Float window"
2028
2222
  title="Float"
2029
- @click=${() => this.handleDockClick('floating')}
2223
+ @click=${() => this.handleDockClick("floating")}
2030
2224
  >
2031
2225
  ${this.renderIcon("Maximize2")}
2032
2226
  </button>
@@ -2035,16 +2229,16 @@ export class WebInspectorElement extends LitElement {
2035
2229
  }
2036
2230
 
2037
2231
  private getDockedWindowStyles(): Record<string, string> {
2038
- if (this.dockMode === 'docked-left') {
2232
+ if (this.dockMode === "docked-left") {
2039
2233
  return {
2040
- position: 'fixed',
2041
- top: '0',
2042
- left: '0',
2043
- bottom: '0',
2234
+ position: "fixed",
2235
+ top: "0",
2236
+ left: "0",
2237
+ bottom: "0",
2044
2238
  width: `${Math.round(this.contextState.window.size.width)}px`,
2045
- height: '100vh',
2239
+ height: "100vh",
2046
2240
  minWidth: `${MIN_WINDOW_WIDTH_DOCKED_LEFT}px`,
2047
- borderRadius: '0',
2241
+ borderRadius: "0",
2048
2242
  };
2049
2243
  }
2050
2244
  // Default to floating styles
@@ -2060,19 +2254,37 @@ export class WebInspectorElement extends LitElement {
2060
2254
  this.setDockMode(mode);
2061
2255
  }
2062
2256
 
2063
- private serializeAttributes(attributes: Record<string, string | number | undefined>): string {
2257
+ private serializeAttributes(
2258
+ attributes: Record<string, string | number | undefined>,
2259
+ ): string {
2064
2260
  return Object.entries(attributes)
2065
- .filter(([key, value]) => key !== "key" && value !== undefined && value !== null && value !== "")
2066
- .map(([key, value]) => `${key}="${String(value).replace(/"/g, "&quot;")}"`)
2261
+ .filter(
2262
+ ([key, value]) =>
2263
+ key !== "key" &&
2264
+ value !== undefined &&
2265
+ value !== null &&
2266
+ value !== "",
2267
+ )
2268
+ .map(
2269
+ ([key, value]) => `${key}="${String(value).replace(/"/g, "&quot;")}"`,
2270
+ )
2067
2271
  .join(" ");
2068
2272
  }
2069
2273
 
2070
- private sanitizeForLogging(value: unknown, depth = 0, seen = new WeakSet<object>()): SanitizedValue {
2274
+ private sanitizeForLogging(
2275
+ value: unknown,
2276
+ depth = 0,
2277
+ seen = new WeakSet<object>(),
2278
+ ): SanitizedValue {
2071
2279
  if (value === undefined) {
2072
2280
  return "[undefined]";
2073
2281
  }
2074
2282
 
2075
- if (value === null || typeof value === "number" || typeof value === "boolean") {
2283
+ if (
2284
+ value === null ||
2285
+ typeof value === "number" ||
2286
+ typeof value === "boolean"
2287
+ ) {
2076
2288
  return value;
2077
2289
  }
2078
2290
 
@@ -2080,7 +2292,11 @@ export class WebInspectorElement extends LitElement {
2080
2292
  return value;
2081
2293
  }
2082
2294
 
2083
- if (typeof value === "bigint" || typeof value === "symbol" || typeof value === "function") {
2295
+ if (
2296
+ typeof value === "bigint" ||
2297
+ typeof value === "symbol" ||
2298
+ typeof value === "function"
2299
+ ) {
2084
2300
  return String(value);
2085
2301
  }
2086
2302
 
@@ -2092,7 +2308,9 @@ export class WebInspectorElement extends LitElement {
2092
2308
  if (depth >= 4) {
2093
2309
  return "[Truncated depth]" as SanitizedValue;
2094
2310
  }
2095
- return value.map((item) => this.sanitizeForLogging(item, depth + 1, seen));
2311
+ return value.map((item) =>
2312
+ this.sanitizeForLogging(item, depth + 1, seen),
2313
+ );
2096
2314
  }
2097
2315
 
2098
2316
  if (typeof value === "object") {
@@ -2106,7 +2324,9 @@ export class WebInspectorElement extends LitElement {
2106
2324
  }
2107
2325
 
2108
2326
  const result: Record<string, SanitizedValue> = {};
2109
- for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {
2327
+ for (const [key, entry] of Object.entries(
2328
+ value as Record<string, unknown>,
2329
+ )) {
2110
2330
  result[key] = this.sanitizeForLogging(entry, depth + 1, seen);
2111
2331
  }
2112
2332
  return result;
@@ -2115,10 +2335,14 @@ export class WebInspectorElement extends LitElement {
2115
2335
  return String(value);
2116
2336
  }
2117
2337
 
2118
- private normalizeEventPayload(_type: InspectorAgentEventType, payload: unknown): SanitizedValue {
2338
+ private normalizeEventPayload(
2339
+ _type: InspectorAgentEventType,
2340
+ payload: unknown,
2341
+ ): SanitizedValue {
2119
2342
  if (payload && typeof payload === "object" && "event" in payload) {
2120
2343
  const { event, ...rest } = payload as Record<string, unknown>;
2121
- const cleaned = Object.keys(rest).length === 0 ? event : { event, ...rest };
2344
+ const cleaned =
2345
+ Object.keys(rest).length === 0 ? event : { event, ...rest };
2122
2346
  return this.sanitizeForLogging(cleaned);
2123
2347
  }
2124
2348
 
@@ -2130,7 +2354,11 @@ export class WebInspectorElement extends LitElement {
2130
2354
  return content;
2131
2355
  }
2132
2356
 
2133
- if (content && typeof content === "object" && "text" in (content as Record<string, unknown>)) {
2357
+ if (
2358
+ content &&
2359
+ typeof content === "object" &&
2360
+ "text" in (content as Record<string, unknown>)
2361
+ ) {
2134
2362
  const maybeText = (content as Record<string, unknown>).text;
2135
2363
  if (typeof maybeText === "string") {
2136
2364
  return maybeText;
@@ -2164,12 +2392,21 @@ export class WebInspectorElement extends LitElement {
2164
2392
  }
2165
2393
  const call = entry as Record<string, unknown>;
2166
2394
  const fn = call.function as Record<string, unknown> | undefined;
2167
- const functionName = typeof fn?.name === "string" ? fn.name : typeof call.toolName === "string" ? call.toolName : undefined;
2168
- const args = fn && "arguments" in fn ? (fn as Record<string, unknown>).arguments : call.arguments;
2395
+ const functionName =
2396
+ typeof fn?.name === "string"
2397
+ ? fn.name
2398
+ : typeof call.toolName === "string"
2399
+ ? call.toolName
2400
+ : undefined;
2401
+ const args =
2402
+ fn && "arguments" in fn
2403
+ ? (fn as Record<string, unknown>).arguments
2404
+ : call.arguments;
2169
2405
 
2170
2406
  const normalized: InspectorToolCall = {
2171
2407
  id: typeof call.id === "string" ? call.id : undefined,
2172
- toolName: typeof call.toolName === "string" ? call.toolName : functionName,
2408
+ toolName:
2409
+ typeof call.toolName === "string" ? call.toolName : functionName,
2173
2410
  status: typeof call.status === "string" ? call.status : undefined,
2174
2411
  };
2175
2412
 
@@ -2199,7 +2436,10 @@ export class WebInspectorElement extends LitElement {
2199
2436
  id: typeof raw.id === "string" ? raw.id : undefined,
2200
2437
  role,
2201
2438
  contentText,
2202
- contentRaw: raw.content !== undefined ? this.sanitizeForLogging(raw.content) : undefined,
2439
+ contentRaw:
2440
+ raw.content !== undefined
2441
+ ? this.sanitizeForLogging(raw.content)
2442
+ : undefined,
2203
2443
  toolCalls,
2204
2444
  };
2205
2445
  }
@@ -2223,12 +2463,18 @@ export class WebInspectorElement extends LitElement {
2223
2463
  return {};
2224
2464
  }
2225
2465
 
2226
- const normalized: Record<string, { description?: string; value: unknown }> = {};
2466
+ const normalized: Record<string, { description?: string; value: unknown }> =
2467
+ {};
2227
2468
  for (const [key, entry] of Object.entries(context)) {
2228
- if (entry && typeof entry === "object" && "value" in (entry as Record<string, unknown>)) {
2469
+ if (
2470
+ entry &&
2471
+ typeof entry === "object" &&
2472
+ "value" in (entry as Record<string, unknown>)
2473
+ ) {
2229
2474
  const candidate = entry as Record<string, unknown>;
2230
2475
  const description =
2231
- typeof candidate.description === "string" && candidate.description.trim().length > 0
2476
+ typeof candidate.description === "string" &&
2477
+ candidate.description.trim().length > 0
2232
2478
  ? candidate.description
2233
2479
  : undefined;
2234
2480
  normalized[key] = { description, value: candidate.value };
@@ -2262,12 +2508,19 @@ export class WebInspectorElement extends LitElement {
2262
2508
  }
2263
2509
 
2264
2510
  return html`
2265
- <div 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">
2266
- <span class="mt-0.5 shrink-0 text-amber-600">${this.renderIcon("AlertTriangle")}</span>
2511
+ <div
2512
+ 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"
2513
+ >
2514
+ <span class="mt-0.5 shrink-0 text-amber-600"
2515
+ >${this.renderIcon("AlertTriangle")}</span
2516
+ >
2267
2517
  <div class="space-y-1">
2268
- <div class="font-semibold text-amber-900">CopilotKit core not attached</div>
2518
+ <div class="font-semibold text-amber-900">
2519
+ CopilotKit core not attached
2520
+ </div>
2269
2521
  <p class="text-[11px] leading-snug text-amber-800">
2270
- Pass a live <code>CopilotKitCore</code> instance to <code>&lt;cpk-web-inspector&gt;</code> or expose it on
2522
+ Pass a live <code>CopilotKitCore</code> instance to
2523
+ <code>&lt;cpk-web-inspector&gt;</code> or expose it on
2271
2524
  <code>window.__COPILOTKIT_CORE__</code> for auto-attach.
2272
2525
  </p>
2273
2526
  </div>
@@ -2275,23 +2528,30 @@ export class WebInspectorElement extends LitElement {
2275
2528
  `;
2276
2529
  }
2277
2530
 
2278
- private getCoreStatusSummary(): { label: string; tone: string; description: string } {
2531
+ private getCoreStatusSummary(): {
2532
+ label: string;
2533
+ tone: string;
2534
+ description: string;
2535
+ } {
2279
2536
  if (!this._core) {
2280
2537
  return {
2281
2538
  label: "Core not attached",
2282
2539
  tone: "border border-amber-200 bg-amber-50 text-amber-800",
2283
- description: "Pass a CopilotKitCore instance to <cpk-web-inspector> or enable auto-attach.",
2540
+ description:
2541
+ "Pass a CopilotKitCore instance to <cpk-web-inspector> or enable auto-attach.",
2284
2542
  };
2285
2543
  }
2286
2544
 
2287
- const status = this.runtimeStatus ?? CopilotKitCoreRuntimeConnectionStatus.Disconnected;
2545
+ const status =
2546
+ this.runtimeStatus ?? CopilotKitCoreRuntimeConnectionStatus.Disconnected;
2288
2547
  const lastErrorMessage = this.lastCoreError?.message;
2289
2548
 
2290
2549
  if (status === CopilotKitCoreRuntimeConnectionStatus.Error) {
2291
2550
  return {
2292
2551
  label: "Runtime error",
2293
2552
  tone: "border border-rose-200 bg-rose-50 text-rose-700",
2294
- description: lastErrorMessage ?? "CopilotKit runtime reported an error.",
2553
+ description:
2554
+ lastErrorMessage ?? "CopilotKit runtime reported an error.",
2295
2555
  };
2296
2556
  }
2297
2557
 
@@ -2314,7 +2574,8 @@ export class WebInspectorElement extends LitElement {
2314
2574
  return {
2315
2575
  label: "Disconnected",
2316
2576
  tone: "border border-gray-200 bg-gray-50 text-gray-700",
2317
- description: lastErrorMessage ?? "Waiting for CopilotKit runtime to connect.",
2577
+ description:
2578
+ lastErrorMessage ?? "Waiting for CopilotKit runtime to connect.",
2318
2579
  };
2319
2580
  }
2320
2581
 
@@ -2341,17 +2602,26 @@ export class WebInspectorElement extends LitElement {
2341
2602
  private renderEventsTable() {
2342
2603
  const events = this.getEventsForSelectedContext();
2343
2604
  const filteredEvents = this.filterEvents(events);
2344
- const selectedLabel = this.selectedContext === "all-agents" ? "all agents" : `agent ${this.selectedContext}`;
2605
+ const selectedLabel =
2606
+ this.selectedContext === "all-agents"
2607
+ ? "all agents"
2608
+ : `agent ${this.selectedContext}`;
2345
2609
 
2346
2610
  if (events.length === 0) {
2347
2611
  return html`
2348
- <div class="flex h-full items-center justify-center px-4 py-8 text-center">
2612
+ <div
2613
+ class="flex h-full items-center justify-center px-4 py-8 text-center"
2614
+ >
2349
2615
  <div class="max-w-md">
2350
- <div class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8">
2616
+ <div
2617
+ class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8"
2618
+ >
2351
2619
  ${this.renderIcon("Zap")}
2352
2620
  </div>
2353
2621
  <p class="text-sm text-gray-600">No events yet</p>
2354
- <p class="mt-2 text-xs text-gray-500">Trigger an agent run to see live activity.</p>
2622
+ <p class="mt-2 text-xs text-gray-500">
2623
+ Trigger an agent run to see live activity.
2624
+ </p>
2355
2625
  </div>
2356
2626
  </div>
2357
2627
  `;
@@ -2359,12 +2629,18 @@ export class WebInspectorElement extends LitElement {
2359
2629
 
2360
2630
  if (filteredEvents.length === 0) {
2361
2631
  return html`
2362
- <div class="flex h-full items-center justify-center px-4 py-8 text-center">
2632
+ <div
2633
+ class="flex h-full items-center justify-center px-4 py-8 text-center"
2634
+ >
2363
2635
  <div class="max-w-md space-y-3">
2364
- <div class="flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8">
2636
+ <div
2637
+ class="flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8"
2638
+ >
2365
2639
  ${this.renderIcon("Filter")}
2366
2640
  </div>
2367
- <p class="text-sm text-gray-600">No events match the current filters.</p>
2641
+ <p class="text-sm text-gray-600">
2642
+ No events match the current filters.
2643
+ </p>
2368
2644
  <div>
2369
2645
  <button
2370
2646
  type="button"
@@ -2382,7 +2658,9 @@ export class WebInspectorElement extends LitElement {
2382
2658
 
2383
2659
  return html`
2384
2660
  <div class="flex h-full flex-col">
2385
- <div class="flex flex-col gap-1.5 border-b border-gray-200 bg-white px-4 py-2.5">
2661
+ <div
2662
+ class="flex flex-col gap-1.5 border-b border-gray-200 bg-white px-4 py-2.5"
2663
+ >
2386
2664
  <div class="flex flex-wrap items-center gap-2">
2387
2665
  <div class="relative min-w-[200px] flex-1">
2388
2666
  <input
@@ -2401,7 +2679,9 @@ export class WebInspectorElement extends LitElement {
2401
2679
  <option value="all">All event types</option>
2402
2680
  ${AGENT_EVENT_TYPES.map(
2403
2681
  (type) =>
2404
- html`<option value=${type}>${type.toLowerCase().replace(/_/g, " ")}</option>`,
2682
+ html`<option value=${type}>
2683
+ ${type.toLowerCase().replace(/_/g, " ")}
2684
+ </option>`,
2405
2685
  )}
2406
2686
  </select>
2407
2687
  <div class="flex items-center gap-1 text-[11px]">
@@ -2412,7 +2692,8 @@ export class WebInspectorElement extends LitElement {
2412
2692
  data-tooltip="Reset filters"
2413
2693
  aria-label="Reset filters"
2414
2694
  @click=${this.resetEventFilters}
2415
- ?disabled=${!this.eventFilterText && this.eventTypeFilter === "all"}
2695
+ ?disabled=${!this.eventFilterText &&
2696
+ this.eventTypeFilter === "all"}
2416
2697
  >
2417
2698
  ${this.renderIcon("RotateCw")}
2418
2699
  </button>
@@ -2441,23 +2722,34 @@ export class WebInspectorElement extends LitElement {
2441
2722
  </div>
2442
2723
  </div>
2443
2724
  <div class="text-[11px] text-gray-500">
2444
- Showing ${filteredEvents.length} of ${events.length}${this.selectedContext === "all-agents" ? "" : ` for ${selectedLabel}`}
2725
+ Showing ${filteredEvents.length} of
2726
+ ${events.length}${this.selectedContext === "all-agents"
2727
+ ? ""
2728
+ : ` for ${selectedLabel}`}
2445
2729
  </div>
2446
2730
  </div>
2447
2731
  <div class="relative h-full w-full overflow-y-auto overflow-x-hidden">
2448
2732
  <table class="w-full table-fixed border-collapse text-xs box-border">
2449
2733
  <thead class="sticky top-0 z-10">
2450
2734
  <tr class="bg-white">
2451
- <th class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900">
2735
+ <th
2736
+ class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
2737
+ >
2452
2738
  Agent
2453
2739
  </th>
2454
- <th class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900">
2740
+ <th
2741
+ class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
2742
+ >
2455
2743
  Time
2456
2744
  </th>
2457
- <th class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900">
2745
+ <th
2746
+ class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
2747
+ >
2458
2748
  Event Type
2459
2749
  </th>
2460
- <th class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900">
2750
+ <th
2751
+ class="border-b border-gray-200 bg-white px-3 py-2 text-left font-medium text-gray-900"
2752
+ >
2461
2753
  AG-UI Event
2462
2754
  </th>
2463
2755
  </tr>
@@ -2466,9 +2758,13 @@ export class WebInspectorElement extends LitElement {
2466
2758
  ${filteredEvents.map((event, index) => {
2467
2759
  const rowBg = index % 2 === 0 ? "bg-white" : "bg-gray-50/50";
2468
2760
  const badgeClasses = this.getEventBadgeClasses(event.type);
2469
- const extractedEvent = this.extractEventFromPayload(event.payload);
2470
- const inlineEvent = this.stringifyPayload(extractedEvent, false) || "—";
2471
- const prettyEvent = this.stringifyPayload(extractedEvent, true) || inlineEvent;
2761
+ const extractedEvent = this.extractEventFromPayload(
2762
+ event.payload,
2763
+ );
2764
+ const inlineEvent =
2765
+ this.stringifyPayload(extractedEvent, false) || "—";
2766
+ const prettyEvent =
2767
+ this.stringifyPayload(extractedEvent, true) || inlineEvent;
2472
2768
  const isExpanded = this.expandedRows.has(event.id);
2473
2769
 
2474
2770
  return html`
@@ -2476,10 +2772,16 @@ export class WebInspectorElement extends LitElement {
2476
2772
  class="${rowBg} cursor-pointer transition hover:bg-blue-50/50"
2477
2773
  @click=${() => this.toggleRowExpansion(event.id)}
2478
2774
  >
2479
- <td class="border-l border-r border-b border-gray-200 px-3 py-2">
2480
- <span class="font-mono text-[11px] text-gray-600">${event.agentId}</span>
2775
+ <td
2776
+ class="border-l border-r border-b border-gray-200 px-3 py-2"
2777
+ >
2778
+ <span class="font-mono text-[11px] text-gray-600"
2779
+ >${event.agentId}</span
2780
+ >
2481
2781
  </td>
2482
- <td class="border-r border-b border-gray-200 px-3 py-2 font-mono text-[11px] text-gray-600">
2782
+ <td
2783
+ class="border-r border-b border-gray-200 px-3 py-2 font-mono text-[11px] text-gray-600"
2784
+ >
2483
2785
  <span title=${new Date(event.timestamp).toLocaleString()}>
2484
2786
  ${new Date(event.timestamp).toLocaleTimeString()}
2485
2787
  </span>
@@ -2487,17 +2789,25 @@ export class WebInspectorElement extends LitElement {
2487
2789
  <td class="border-r border-b border-gray-200 px-3 py-2">
2488
2790
  <span class=${badgeClasses}>${event.type}</span>
2489
2791
  </td>
2490
- <td class="border-r border-b border-gray-200 px-3 py-2 font-mono text-[10px] text-gray-600 ${isExpanded ? '' : 'truncate max-w-xs'}">
2792
+ <td
2793
+ class="border-r border-b border-gray-200 px-3 py-2 font-mono text-[10px] text-gray-600 ${isExpanded
2794
+ ? ""
2795
+ : "truncate max-w-xs"}"
2796
+ >
2491
2797
  ${isExpanded
2492
2798
  ? html`
2493
2799
  <div class="group relative">
2494
- <pre class="m-0 whitespace-pre-wrap break-words text-[10px] font-mono text-gray-600">${prettyEvent}</pre>
2800
+ <pre
2801
+ class="m-0 whitespace-pre-wrap break-words text-[10px] font-mono text-gray-600"
2802
+ >
2803
+ ${prettyEvent}</pre
2804
+ >
2495
2805
  <button
2496
- class="absolute right-0 top-0 cursor-pointer rounded px-2 py-1 text-[10px] opacity-0 transition group-hover:opacity-100 ${
2497
- this.copiedEvents.has(event.id)
2498
- ? 'bg-green-100 text-green-700'
2499
- : 'bg-gray-100 text-gray-600 hover:bg-gray-200 hover:text-gray-900'
2500
- }"
2806
+ 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(
2807
+ event.id,
2808
+ )
2809
+ ? "bg-green-100 text-green-700"
2810
+ : "bg-gray-100 text-gray-600 hover:bg-gray-200 hover:text-gray-900"}"
2501
2811
  @click=${(e: Event) => {
2502
2812
  e.stopPropagation();
2503
2813
  this.copyToClipboard(prettyEvent, event.id);
@@ -2549,7 +2859,9 @@ export class WebInspectorElement extends LitElement {
2549
2859
  this.flattenedEvents = [];
2550
2860
  } else {
2551
2861
  this.agentEvents.delete(this.selectedContext);
2552
- this.flattenedEvents = this.flattenedEvents.filter((event) => event.agentId !== this.selectedContext);
2862
+ this.flattenedEvents = this.flattenedEvents.filter(
2863
+ (event) => event.agentId !== this.selectedContext,
2864
+ );
2553
2865
  }
2554
2866
 
2555
2867
  this.expandedRows.clear();
@@ -2576,13 +2888,19 @@ export class WebInspectorElement extends LitElement {
2576
2888
  // Show message if "all-agents" is selected or no agents available
2577
2889
  if (this.selectedContext === "all-agents") {
2578
2890
  return html`
2579
- <div class="flex h-full items-center justify-center px-4 py-8 text-center">
2891
+ <div
2892
+ class="flex h-full items-center justify-center px-4 py-8 text-center"
2893
+ >
2580
2894
  <div class="max-w-md">
2581
- <div class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8">
2895
+ <div
2896
+ class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8"
2897
+ >
2582
2898
  ${this.renderIcon("Bot")}
2583
2899
  </div>
2584
2900
  <p class="text-sm text-gray-600">No agent selected</p>
2585
- <p class="mt-2 text-xs text-gray-500">Select an agent from the dropdown above to view details.</p>
2901
+ <p class="mt-2 text-xs text-gray-500">
2902
+ Select an agent from the dropdown above to view details.
2903
+ </p>
2586
2904
  </div>
2587
2905
  </div>
2588
2906
  `;
@@ -2606,19 +2924,34 @@ export class WebInspectorElement extends LitElement {
2606
2924
  <div class="rounded-lg border border-gray-200 bg-white p-4">
2607
2925
  <div class="flex items-start justify-between mb-4">
2608
2926
  <div class="flex items-center gap-3">
2609
- <div class="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600">
2927
+ <div
2928
+ class="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600"
2929
+ >
2610
2930
  ${this.renderIcon("Bot")}
2611
2931
  </div>
2612
2932
  <div>
2613
2933
  <h3 class="font-semibold text-sm text-gray-900">${agentId}</h3>
2614
- <span class="inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[status]} relative -translate-y-[2px]">
2615
- <span class="h-1.5 w-1.5 rounded-full ${status === 'running' ? 'bg-emerald-500 animate-pulse' : status === 'error' ? 'bg-rose-500' : 'bg-gray-400'}"></span>
2934
+ <span
2935
+ class="inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium ${statusColors[
2936
+ status
2937
+ ]} relative -translate-y-[2px]"
2938
+ >
2939
+ <span
2940
+ class="h-1.5 w-1.5 rounded-full ${status === "running"
2941
+ ? "bg-emerald-500 animate-pulse"
2942
+ : status === "error"
2943
+ ? "bg-rose-500"
2944
+ : "bg-gray-400"}"
2945
+ ></span>
2616
2946
  ${status.charAt(0).toUpperCase() + status.slice(1)}
2617
2947
  </span>
2618
2948
  </div>
2619
2949
  </div>
2620
2950
  ${stats.lastActivity
2621
- ? html`<span class="text-xs text-gray-500">Last activity: ${new Date(stats.lastActivity).toLocaleTimeString()}</span>`
2951
+ ? html`<span class="text-xs text-gray-500"
2952
+ >Last activity:
2953
+ ${new Date(stats.lastActivity).toLocaleTimeString()}</span
2954
+ >`
2622
2955
  : nothing}
2623
2956
  </div>
2624
2957
  <div class="grid grid-cols-2 gap-4 md:grid-cols-4">
@@ -2628,20 +2961,36 @@ export class WebInspectorElement extends LitElement {
2628
2961
  @click=${() => this.handleMenuSelect("ag-ui-events")}
2629
2962
  title="View all events in AG-UI Events"
2630
2963
  >
2631
- <div class="truncate whitespace-nowrap text-xs text-gray-600">Total Events</div>
2632
- <div class="text-lg font-semibold text-gray-900">${stats.totalEvents}</div>
2964
+ <div class="truncate whitespace-nowrap text-xs text-gray-600">
2965
+ Total Events
2966
+ </div>
2967
+ <div class="text-lg font-semibold text-gray-900">
2968
+ ${stats.totalEvents}
2969
+ </div>
2633
2970
  </button>
2634
2971
  <div class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden">
2635
- <div class="truncate whitespace-nowrap text-xs text-gray-600">Messages</div>
2636
- <div class="text-lg font-semibold text-gray-900">${stats.messages}</div>
2972
+ <div class="truncate whitespace-nowrap text-xs text-gray-600">
2973
+ Messages
2974
+ </div>
2975
+ <div class="text-lg font-semibold text-gray-900">
2976
+ ${stats.messages}
2977
+ </div>
2637
2978
  </div>
2638
2979
  <div class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden">
2639
- <div class="truncate whitespace-nowrap text-xs text-gray-600">Tool Calls</div>
2640
- <div class="text-lg font-semibold text-gray-900">${stats.toolCalls}</div>
2980
+ <div class="truncate whitespace-nowrap text-xs text-gray-600">
2981
+ Tool Calls
2982
+ </div>
2983
+ <div class="text-lg font-semibold text-gray-900">
2984
+ ${stats.toolCalls}
2985
+ </div>
2641
2986
  </div>
2642
2987
  <div class="rounded-md bg-gray-50 px-3 py-2 overflow-hidden">
2643
- <div class="truncate whitespace-nowrap text-xs text-gray-600">Errors</div>
2644
- <div class="text-lg font-semibold text-gray-900">${stats.errors}</div>
2988
+ <div class="truncate whitespace-nowrap text-xs text-gray-600">
2989
+ Errors
2990
+ </div>
2991
+ <div class="text-lg font-semibold text-gray-900">
2992
+ ${stats.errors}
2993
+ </div>
2645
2994
  </div>
2646
2995
  </div>
2647
2996
  </div>
@@ -2654,12 +3003,18 @@ export class WebInspectorElement extends LitElement {
2654
3003
  <div class="overflow-auto p-4">
2655
3004
  ${this.hasRenderableState(state)
2656
3005
  ? html`
2657
- <pre class="overflow-auto rounded-md bg-gray-50 p-3 text-xs text-gray-800 max-h-64"><code>${this.formatStateForDisplay(state)}</code></pre>
3006
+ <pre
3007
+ class="overflow-auto rounded-md bg-gray-50 p-3 text-xs text-gray-800 max-h-64"
3008
+ ><code>${this.formatStateForDisplay(state)}</code></pre>
2658
3009
  `
2659
3010
  : html`
2660
- <div class="flex h-40 items-center justify-center text-xs text-gray-500">
3011
+ <div
3012
+ class="flex h-40 items-center justify-center text-xs text-gray-500"
3013
+ >
2661
3014
  <div class="flex items-center gap-2 text-gray-500">
2662
- <span class="text-lg text-gray-400">${this.renderIcon("Database")}</span>
3015
+ <span class="text-lg text-gray-400"
3016
+ >${this.renderIcon("Database")}</span
3017
+ >
2663
3018
  <span>State is empty</span>
2664
3019
  </div>
2665
3020
  </div>
@@ -2670,7 +3025,9 @@ export class WebInspectorElement extends LitElement {
2670
3025
  <!-- Current Messages Section -->
2671
3026
  <div class="rounded-lg border border-gray-200 bg-white">
2672
3027
  <div class="border-b border-gray-200 px-4 py-3">
2673
- <h4 class="text-sm font-semibold text-gray-900">Current Messages</h4>
3028
+ <h4 class="text-sm font-semibold text-gray-900">
3029
+ Current Messages
3030
+ </h4>
2674
3031
  </div>
2675
3032
  <div class="overflow-auto">
2676
3033
  ${messages && messages.length > 0
@@ -2678,8 +3035,16 @@ export class WebInspectorElement extends LitElement {
2678
3035
  <table class="w-full text-xs">
2679
3036
  <thead class="bg-gray-50">
2680
3037
  <tr>
2681
- <th class="px-4 py-2 text-left font-medium text-gray-700">Role</th>
2682
- <th class="px-4 py-2 text-left font-medium text-gray-700">Content</th>
3038
+ <th
3039
+ class="px-4 py-2 text-left font-medium text-gray-700"
3040
+ >
3041
+ Role
3042
+ </th>
3043
+ <th
3044
+ class="px-4 py-2 text-left font-medium text-gray-700"
3045
+ >
3046
+ Content
3047
+ </th>
2683
3048
  </tr>
2684
3049
  </thead>
2685
3050
  <tbody class="divide-y divide-gray-200">
@@ -2696,20 +3061,33 @@ export class WebInspectorElement extends LitElement {
2696
3061
  const rawContent = msg.contentText ?? "";
2697
3062
  const toolCalls = msg.toolCalls ?? [];
2698
3063
  const hasContent = rawContent.trim().length > 0;
2699
- const contentFallback = toolCalls.length > 0 ? "Invoked tool call" : "—";
3064
+ const contentFallback =
3065
+ toolCalls.length > 0 ? "Invoked tool call" : "—";
2700
3066
 
2701
3067
  return html`
2702
3068
  <tr>
2703
3069
  <td class="px-4 py-2 align-top">
2704
- <span class="inline-flex rounded px-2 py-0.5 text-[10px] font-medium ${roleColors[role] || roleColors.unknown}">
3070
+ <span
3071
+ class="inline-flex rounded px-2 py-0.5 text-[10px] font-medium ${roleColors[
3072
+ role
3073
+ ] || roleColors.unknown}"
3074
+ >
2705
3075
  ${role}
2706
3076
  </span>
2707
3077
  </td>
2708
3078
  <td class="px-4 py-2">
2709
3079
  ${hasContent
2710
- ? html`<div class="max-w-2xl whitespace-pre-wrap break-words text-gray-700">${rawContent}</div>`
2711
- : html`<div class="text-xs italic text-gray-400">${contentFallback}</div>`}
2712
- ${role === 'assistant' && toolCalls.length > 0
3080
+ ? html`<div
3081
+ class="max-w-2xl whitespace-pre-wrap break-words text-gray-700"
3082
+ >
3083
+ ${rawContent}
3084
+ </div>`
3085
+ : html`<div
3086
+ class="text-xs italic text-gray-400"
3087
+ >
3088
+ ${contentFallback}
3089
+ </div>`}
3090
+ ${role === "assistant" && toolCalls.length > 0
2713
3091
  ? this.renderToolCallDetails(toolCalls)
2714
3092
  : nothing}
2715
3093
  </td>
@@ -2720,9 +3098,13 @@ export class WebInspectorElement extends LitElement {
2720
3098
  </table>
2721
3099
  `
2722
3100
  : html`
2723
- <div class="flex h-40 items-center justify-center text-xs text-gray-500">
3101
+ <div
3102
+ class="flex h-40 items-center justify-center text-xs text-gray-500"
3103
+ >
2724
3104
  <div class="flex items-center gap-2 text-gray-500">
2725
- <span class="text-lg text-gray-400">${this.renderIcon("MessageSquare")}</span>
3105
+ <span class="text-lg text-gray-400"
3106
+ >${this.renderIcon("MessageSquare")}</span
3107
+ >
2726
3108
  <span>No messages available</span>
2727
3109
  </div>
2728
3110
  </div>
@@ -2735,21 +3117,29 @@ export class WebInspectorElement extends LitElement {
2735
3117
 
2736
3118
  private renderContextDropdown() {
2737
3119
  // Filter out "all-agents" when in agents view
2738
- const filteredOptions = this.selectedMenu === "agents"
2739
- ? this.contextOptions.filter((opt) => opt.key !== "all-agents")
2740
- : this.contextOptions;
3120
+ const filteredOptions =
3121
+ this.selectedMenu === "agents"
3122
+ ? this.contextOptions.filter((opt) => opt.key !== "all-agents")
3123
+ : this.contextOptions;
2741
3124
 
2742
- const selectedLabel = filteredOptions.find((opt) => opt.key === this.selectedContext)?.label ?? "";
3125
+ const selectedLabel =
3126
+ filteredOptions.find((opt) => opt.key === this.selectedContext)?.label ??
3127
+ "";
2743
3128
 
2744
3129
  return html`
2745
- <div class="relative z-40 min-w-0 flex-1" data-context-dropdown-root="true">
3130
+ <div
3131
+ class="relative z-40 min-w-0 flex-1"
3132
+ data-context-dropdown-root="true"
3133
+ >
2746
3134
  <button
2747
3135
  type="button"
2748
3136
  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"
2749
3137
  @pointerdown=${this.handleContextDropdownToggle}
2750
3138
  >
2751
3139
  <span class="truncate flex-1 text-left">${selectedLabel}</span>
2752
- <span class="shrink-0 text-gray-400">${this.renderIcon("ChevronDown")}</span>
3140
+ <span class="shrink-0 text-gray-400"
3141
+ >${this.renderIcon("ChevronDown")}</span
3142
+ >
2753
3143
  </button>
2754
3144
  ${this.contextMenuOpen
2755
3145
  ? html`
@@ -2765,9 +3155,16 @@ export class WebInspectorElement extends LitElement {
2765
3155
  data-context-dropdown-root="true"
2766
3156
  @click=${() => this.handleContextOptionSelect(option.key)}
2767
3157
  >
2768
- <span class="truncate ${option.key === this.selectedContext ? 'text-gray-900 font-medium' : 'text-gray-600'}">${option.label}</span>
3158
+ <span
3159
+ class="truncate ${option.key === this.selectedContext
3160
+ ? "text-gray-900 font-medium"
3161
+ : "text-gray-600"}"
3162
+ >${option.label}</span
3163
+ >
2769
3164
  ${option.key === this.selectedContext
2770
- ? html`<span class="text-gray-500">${this.renderIcon("Check")}</span>`
3165
+ ? html`<span class="text-gray-500"
3166
+ >${this.renderIcon("Check")}</span
3167
+ >`
2771
3168
  : nothing}
2772
3169
  </button>
2773
3170
  `,
@@ -2788,11 +3185,15 @@ export class WebInspectorElement extends LitElement {
2788
3185
 
2789
3186
  // If switching to agents view and "all-agents" is selected, switch to default or first agent
2790
3187
  if (key === "agents" && this.selectedContext === "all-agents") {
2791
- const agentOptions = this.contextOptions.filter((opt) => opt.key !== "all-agents");
3188
+ const agentOptions = this.contextOptions.filter(
3189
+ (opt) => opt.key !== "all-agents",
3190
+ );
2792
3191
  if (agentOptions.length > 0) {
2793
3192
  // Try to find "default" agent first
2794
3193
  const defaultAgent = agentOptions.find((opt) => opt.key === "default");
2795
- this.selectedContext = defaultAgent ? defaultAgent.key : agentOptions[0]!.key;
3194
+ this.selectedContext = defaultAgent
3195
+ ? defaultAgent.key
3196
+ : agentOptions[0]!.key;
2796
3197
  }
2797
3198
  }
2798
3199
 
@@ -2826,7 +3227,9 @@ export class WebInspectorElement extends LitElement {
2826
3227
  private renderToolsView() {
2827
3228
  if (!this._core) {
2828
3229
  return html`
2829
- <div class="flex h-full items-center justify-center px-4 py-8 text-xs text-gray-500">
3230
+ <div
3231
+ class="flex h-full items-center justify-center px-4 py-8 text-xs text-gray-500"
3232
+ >
2830
3233
  No core instance available
2831
3234
  </div>
2832
3235
  `;
@@ -2837,28 +3240,38 @@ export class WebInspectorElement extends LitElement {
2837
3240
 
2838
3241
  if (allTools.length === 0) {
2839
3242
  return html`
2840
- <div class="flex h-full items-center justify-center px-4 py-8 text-center">
3243
+ <div
3244
+ class="flex h-full items-center justify-center px-4 py-8 text-center"
3245
+ >
2841
3246
  <div class="max-w-md">
2842
- <div class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8">
3247
+ <div
3248
+ class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8"
3249
+ >
2843
3250
  ${this.renderIcon("Hammer")}
2844
3251
  </div>
2845
3252
  <p class="text-sm text-gray-600">No tools available</p>
2846
- <p class="mt-2 text-xs text-gray-500">Tools will appear here once agents are configured with tool handlers or renderers.</p>
3253
+ <p class="mt-2 text-xs text-gray-500">
3254
+ Tools will appear here once agents are configured with tool
3255
+ handlers or renderers.
3256
+ </p>
2847
3257
  </div>
2848
3258
  </div>
2849
3259
  `;
2850
3260
  }
2851
3261
 
2852
3262
  // Filter tools by selected agent
2853
- const filteredTools = this.selectedContext === "all-agents"
2854
- ? allTools
2855
- : allTools.filter((tool) => !tool.agentId || tool.agentId === this.selectedContext);
3263
+ const filteredTools =
3264
+ this.selectedContext === "all-agents"
3265
+ ? allTools
3266
+ : allTools.filter(
3267
+ (tool) => !tool.agentId || tool.agentId === this.selectedContext,
3268
+ );
2856
3269
 
2857
3270
  return html`
2858
3271
  <div class="flex h-full flex-col overflow-hidden">
2859
3272
  <div class="overflow-auto p-4">
2860
3273
  <div class="space-y-3">
2861
- ${filteredTools.map(tool => this.renderToolCard(tool))}
3274
+ ${filteredTools.map((tool) => this.renderToolCard(tool))}
2862
3275
  </div>
2863
3276
  </div>
2864
3277
  </div>
@@ -2879,7 +3292,7 @@ export class WebInspectorElement extends LitElement {
2879
3292
  name: coreTool.name,
2880
3293
  description: coreTool.description,
2881
3294
  parameters: coreTool.parameters,
2882
- type: 'handler',
3295
+ type: "handler",
2883
3296
  });
2884
3297
  }
2885
3298
 
@@ -2888,44 +3301,54 @@ export class WebInspectorElement extends LitElement {
2888
3301
  if (!agent) continue;
2889
3302
 
2890
3303
  // Try to extract tool handlers
2891
- const handlers = (agent as { toolHandlers?: Record<string, unknown> }).toolHandlers;
2892
- if (handlers && typeof handlers === 'object') {
3304
+ const handlers = (agent as { toolHandlers?: Record<string, unknown> })
3305
+ .toolHandlers;
3306
+ if (handlers && typeof handlers === "object") {
2893
3307
  for (const [toolName, handler] of Object.entries(handlers)) {
2894
- if (handler && typeof handler === 'object') {
3308
+ if (handler && typeof handler === "object") {
2895
3309
  const handlerObj = handler as Record<string, unknown>;
2896
3310
  tools.push({
2897
3311
  agentId,
2898
3312
  name: toolName,
2899
3313
  description:
2900
- (typeof handlerObj.description === "string" && handlerObj.description) ||
2901
- (handlerObj.tool as { description?: string } | undefined)?.description,
3314
+ (typeof handlerObj.description === "string" &&
3315
+ handlerObj.description) ||
3316
+ (handlerObj.tool as { description?: string } | undefined)
3317
+ ?.description,
2902
3318
  parameters:
2903
3319
  handlerObj.parameters ??
2904
- (handlerObj.tool as { parameters?: unknown } | undefined)?.parameters,
2905
- type: 'handler',
3320
+ (handlerObj.tool as { parameters?: unknown } | undefined)
3321
+ ?.parameters,
3322
+ type: "handler",
2906
3323
  });
2907
3324
  }
2908
3325
  }
2909
3326
  }
2910
3327
 
2911
3328
  // Try to extract tool renderers
2912
- const renderers = (agent as { toolRenderers?: Record<string, unknown> }).toolRenderers;
2913
- if (renderers && typeof renderers === 'object') {
3329
+ const renderers = (agent as { toolRenderers?: Record<string, unknown> })
3330
+ .toolRenderers;
3331
+ if (renderers && typeof renderers === "object") {
2914
3332
  for (const [toolName, renderer] of Object.entries(renderers)) {
2915
3333
  // Don't duplicate if we already have it as a handler
2916
- if (!tools.some(t => t.agentId === agentId && t.name === toolName)) {
2917
- if (renderer && typeof renderer === 'object') {
3334
+ if (
3335
+ !tools.some((t) => t.agentId === agentId && t.name === toolName)
3336
+ ) {
3337
+ if (renderer && typeof renderer === "object") {
2918
3338
  const rendererObj = renderer as Record<string, unknown>;
2919
3339
  tools.push({
2920
3340
  agentId,
2921
3341
  name: toolName,
2922
3342
  description:
2923
- (typeof rendererObj.description === "string" && rendererObj.description) ||
2924
- (rendererObj.tool as { description?: string } | undefined)?.description,
3343
+ (typeof rendererObj.description === "string" &&
3344
+ rendererObj.description) ||
3345
+ (rendererObj.tool as { description?: string } | undefined)
3346
+ ?.description,
2925
3347
  parameters:
2926
3348
  rendererObj.parameters ??
2927
- (rendererObj.tool as { parameters?: unknown } | undefined)?.parameters,
2928
- type: 'renderer',
3349
+ (rendererObj.tool as { parameters?: unknown } | undefined)
3350
+ ?.parameters,
3351
+ type: "renderer",
2929
3352
  });
2930
3353
  }
2931
3354
  }
@@ -2954,13 +3377,20 @@ export class WebInspectorElement extends LitElement {
2954
3377
  <button
2955
3378
  type="button"
2956
3379
  class="w-full px-4 py-3 text-left transition hover:bg-gray-50"
2957
- @click=${() => this.toggleToolExpansion(`${tool.agentId}:${tool.name}`)}
3380
+ @click=${() =>
3381
+ this.toggleToolExpansion(`${tool.agentId}:${tool.name}`)}
2958
3382
  >
2959
3383
  <div class="flex items-start justify-between gap-3">
2960
3384
  <div class="flex-1 min-w-0">
2961
3385
  <div class="flex items-center gap-2 mb-1">
2962
- <span class="font-mono text-sm font-semibold text-gray-900">${tool.name}</span>
2963
- <span class="inline-flex items-center rounded-sm border px-1.5 py-0.5 text-[10px] font-medium ${typeColors[tool.type]}">
3386
+ <span class="font-mono text-sm font-semibold text-gray-900"
3387
+ >${tool.name}</span
3388
+ >
3389
+ <span
3390
+ class="inline-flex items-center rounded-sm border px-1.5 py-0.5 text-[10px] font-medium ${typeColors[
3391
+ tool.type
3392
+ ]}"
3393
+ >
2964
3394
  ${tool.type}
2965
3395
  </span>
2966
3396
  </div>
@@ -2972,15 +3402,26 @@ export class WebInspectorElement extends LitElement {
2972
3402
  ${schema.properties.length > 0
2973
3403
  ? html`
2974
3404
  <span class="text-gray-300">•</span>
2975
- <span>${schema.properties.length} parameter${schema.properties.length !== 1 ? 's' : ''}</span>
3405
+ <span
3406
+ >${schema.properties.length}
3407
+ parameter${schema.properties.length !== 1
3408
+ ? "s"
3409
+ : ""}</span
3410
+ >
2976
3411
  `
2977
3412
  : nothing}
2978
3413
  </div>
2979
3414
  ${tool.description
2980
- ? html`<p class="mt-2 text-xs text-gray-600">${tool.description}</p>`
3415
+ ? html`<p class="mt-2 text-xs text-gray-600">
3416
+ ${tool.description}
3417
+ </p>`
2981
3418
  : nothing}
2982
3419
  </div>
2983
- <span class="shrink-0 text-gray-400 transition ${isExpanded ? 'rotate-180' : ''}">
3420
+ <span
3421
+ class="shrink-0 text-gray-400 transition ${isExpanded
3422
+ ? "rotate-180"
3423
+ : ""}"
3424
+ >
2984
3425
  ${this.renderIcon("ChevronDown")}
2985
3426
  </span>
2986
3427
  </div>
@@ -2991,50 +3432,88 @@ export class WebInspectorElement extends LitElement {
2991
3432
  <div class="border-t border-gray-200 bg-gray-50/50 px-4 py-3">
2992
3433
  ${schema.properties.length > 0
2993
3434
  ? html`
2994
- <h5 class="mb-3 text-xs font-semibold text-gray-700">Parameters</h5>
3435
+ <h5 class="mb-3 text-xs font-semibold text-gray-700">
3436
+ Parameters
3437
+ </h5>
2995
3438
  <div class="space-y-3">
2996
- ${schema.properties.map(prop => html`
2997
- <div class="rounded-md border border-gray-200 bg-white p-3">
2998
- <div class="flex items-start justify-between gap-2 mb-1">
2999
- <span class="font-mono text-xs font-medium text-gray-900">${prop.name}</span>
3000
- <div class="flex items-center gap-1.5 shrink-0">
3001
- ${prop.required
3002
- ? html`<span class="text-[9px] rounded border border-rose-200 bg-rose-50 px-1 py-0.5 font-medium text-rose-700">required</span>`
3003
- : html`<span class="text-[9px] rounded border border-gray-200 bg-gray-50 px-1 py-0.5 font-medium text-gray-600">optional</span>`}
3004
- ${prop.type
3005
- ? html`<span class="text-[9px] rounded border border-gray-200 bg-gray-50 px-1 py-0.5 font-mono text-gray-600">${prop.type}</span>`
3006
- : nothing}
3439
+ ${schema.properties.map(
3440
+ (prop) => html`
3441
+ <div
3442
+ class="rounded-md border border-gray-200 bg-white p-3"
3443
+ >
3444
+ <div
3445
+ class="flex items-start justify-between gap-2 mb-1"
3446
+ >
3447
+ <span
3448
+ class="font-mono text-xs font-medium text-gray-900"
3449
+ >${prop.name}</span
3450
+ >
3451
+ <div class="flex items-center gap-1.5 shrink-0">
3452
+ ${prop.required
3453
+ ? html`<span
3454
+ class="text-[9px] rounded border border-rose-200 bg-rose-50 px-1 py-0.5 font-medium text-rose-700"
3455
+ >required</span
3456
+ >`
3457
+ : html`<span
3458
+ class="text-[9px] rounded border border-gray-200 bg-gray-50 px-1 py-0.5 font-medium text-gray-600"
3459
+ >optional</span
3460
+ >`}
3461
+ ${prop.type
3462
+ ? html`<span
3463
+ class="text-[9px] rounded border border-gray-200 bg-gray-50 px-1 py-0.5 font-mono text-gray-600"
3464
+ >${prop.type}</span
3465
+ >`
3466
+ : nothing}
3467
+ </div>
3007
3468
  </div>
3008
- </div>
3009
- ${prop.description
3010
- ? html`<p class="mt-1 text-xs text-gray-600">${prop.description}</p>`
3011
- : nothing}
3012
- ${prop.defaultValue !== undefined
3013
- ? html`
3014
- <div class="mt-2 flex items-center gap-1.5 text-[10px] text-gray-500">
3015
- <span>Default:</span>
3016
- <code class="rounded bg-gray-100 px-1 py-0.5 font-mono">${JSON.stringify(prop.defaultValue)}</code>
3017
- </div>
3018
- `
3019
- : nothing}
3020
- ${prop.enum && prop.enum.length > 0
3021
- ? html`
3022
- <div class="mt-2">
3023
- <span class="text-[10px] text-gray-500">Allowed values:</span>
3024
- <div class="mt-1 flex flex-wrap gap-1">
3025
- ${prop.enum.map(val => html`
3026
- <code class="rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 text-[10px] font-mono text-gray-700">${JSON.stringify(val)}</code>
3027
- `)}
3469
+ ${prop.description
3470
+ ? html`<p class="mt-1 text-xs text-gray-600">
3471
+ ${prop.description}
3472
+ </p>`
3473
+ : nothing}
3474
+ ${prop.defaultValue !== undefined
3475
+ ? html`
3476
+ <div
3477
+ class="mt-2 flex items-center gap-1.5 text-[10px] text-gray-500"
3478
+ >
3479
+ <span>Default:</span>
3480
+ <code
3481
+ class="rounded bg-gray-100 px-1 py-0.5 font-mono"
3482
+ >${JSON.stringify(
3483
+ prop.defaultValue,
3484
+ )}</code
3485
+ >
3028
3486
  </div>
3029
- </div>
3030
- `
3031
- : nothing}
3032
- </div>
3033
- `)}
3487
+ `
3488
+ : nothing}
3489
+ ${prop.enum && prop.enum.length > 0
3490
+ ? html`
3491
+ <div class="mt-2">
3492
+ <span class="text-[10px] text-gray-500"
3493
+ >Allowed values:</span
3494
+ >
3495
+ <div class="mt-1 flex flex-wrap gap-1">
3496
+ ${prop.enum.map(
3497
+ (val) => html`
3498
+ <code
3499
+ class="rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 text-[10px] font-mono text-gray-700"
3500
+ >${JSON.stringify(val)}</code
3501
+ >
3502
+ `,
3503
+ )}
3504
+ </div>
3505
+ </div>
3506
+ `
3507
+ : nothing}
3508
+ </div>
3509
+ `,
3510
+ )}
3034
3511
  </div>
3035
3512
  `
3036
3513
  : html`
3037
- <div class="flex items-center justify-center py-4 text-xs text-gray-500">
3514
+ <div
3515
+ class="flex items-center justify-center py-4 text-xs text-gray-500"
3516
+ >
3038
3517
  <span>No parameters defined</span>
3039
3518
  </div>
3040
3519
  `}
@@ -3066,7 +3545,7 @@ export class WebInspectorElement extends LitElement {
3066
3545
  }>;
3067
3546
  } = { properties: [] };
3068
3547
 
3069
- if (!parameters || typeof parameters !== 'object') {
3548
+ if (!parameters || typeof parameters !== "object") {
3070
3549
  return result;
3071
3550
  }
3072
3551
 
@@ -3074,7 +3553,7 @@ export class WebInspectorElement extends LitElement {
3074
3553
  const zodDef = (parameters as { _def?: Record<string, unknown> })._def;
3075
3554
  if (zodDef && typeof zodDef === "object") {
3076
3555
  // Handle Zod object schema
3077
- if (zodDef.typeName === 'ZodObject') {
3556
+ if (zodDef.typeName === "ZodObject") {
3078
3557
  const rawShape = zodDef.shape;
3079
3558
  const shape =
3080
3559
  typeof rawShape === "function"
@@ -3087,10 +3566,12 @@ export class WebInspectorElement extends LitElement {
3087
3566
  const requiredKeys = new Set<string>();
3088
3567
 
3089
3568
  // Get required fields
3090
- if (zodDef.unknownKeys === 'strict' || !zodDef.catchall) {
3569
+ if (zodDef.unknownKeys === "strict" || !zodDef.catchall) {
3091
3570
  Object.keys(shape || {}).forEach((key) => {
3092
3571
  const candidate = (shape as Record<string, unknown>)[key];
3093
- const fieldDef = (candidate as { _def?: Record<string, unknown> } | undefined)?._def;
3572
+ const fieldDef = (
3573
+ candidate as { _def?: Record<string, unknown> } | undefined
3574
+ )?._def;
3094
3575
  if (fieldDef && !this.isZodOptional(candidate)) {
3095
3576
  requiredKeys.add(key);
3096
3577
  }
@@ -3111,11 +3592,13 @@ export class WebInspectorElement extends LitElement {
3111
3592
  }
3112
3593
  }
3113
3594
  } else if (
3114
- (parameters as { type?: string; properties?: Record<string, unknown> }).type === 'object' &&
3595
+ (parameters as { type?: string; properties?: Record<string, unknown> })
3596
+ .type === "object" &&
3115
3597
  (parameters as { properties?: Record<string, unknown> }).properties
3116
3598
  ) {
3117
3599
  // Handle JSON Schema format
3118
- const props = (parameters as { properties?: Record<string, unknown> }).properties;
3600
+ const props = (parameters as { properties?: Record<string, unknown> })
3601
+ .properties;
3119
3602
  const required = new Set(
3120
3603
  Array.isArray((parameters as { required?: string[] }).required)
3121
3604
  ? (parameters as { required?: string[] }).required
@@ -3127,7 +3610,8 @@ export class WebInspectorElement extends LitElement {
3127
3610
  result.properties.push({
3128
3611
  name: key,
3129
3612
  type: prop.type as string | undefined,
3130
- description: typeof prop.description === "string" ? prop.description : undefined,
3613
+ description:
3614
+ typeof prop.description === "string" ? prop.description : undefined,
3131
3615
  required: required.has(key),
3132
3616
  defaultValue: prop.default,
3133
3617
  enum: Array.isArray(prop.enum) ? prop.enum : undefined,
@@ -3145,7 +3629,7 @@ export class WebInspectorElement extends LitElement {
3145
3629
  const def = schema._def;
3146
3630
 
3147
3631
  // Check if it's explicitly optional or nullable
3148
- if (def.typeName === 'ZodOptional' || def.typeName === 'ZodNullable') {
3632
+ if (def.typeName === "ZodOptional" || def.typeName === "ZodNullable") {
3149
3633
  return true;
3150
3634
  }
3151
3635
 
@@ -3177,39 +3661,51 @@ export class WebInspectorElement extends LitElement {
3177
3661
  let def = currentSchema._def as Record<string, unknown>;
3178
3662
 
3179
3663
  // Unwrap optional/nullable
3180
- while (def.typeName === 'ZodOptional' || def.typeName === 'ZodNullable' || def.typeName === 'ZodDefault') {
3181
- if (def.typeName === 'ZodDefault' && def.defaultValue !== undefined) {
3182
- info.defaultValue = typeof def.defaultValue === 'function' ? def.defaultValue() : def.defaultValue;
3664
+ while (
3665
+ def.typeName === "ZodOptional" ||
3666
+ def.typeName === "ZodNullable" ||
3667
+ def.typeName === "ZodDefault"
3668
+ ) {
3669
+ if (def.typeName === "ZodDefault" && def.defaultValue !== undefined) {
3670
+ info.defaultValue =
3671
+ typeof def.defaultValue === "function"
3672
+ ? def.defaultValue()
3673
+ : def.defaultValue;
3183
3674
  }
3184
- currentSchema = (def.innerType as { _def?: Record<string, unknown> }) ?? currentSchema;
3675
+ currentSchema =
3676
+ (def.innerType as { _def?: Record<string, unknown> }) ?? currentSchema;
3185
3677
  if (!currentSchema?._def) break;
3186
3678
  def = currentSchema._def as Record<string, unknown>;
3187
3679
  }
3188
3680
 
3189
3681
  // Extract description
3190
- info.description = typeof def.description === "string" ? def.description : undefined;
3682
+ info.description =
3683
+ typeof def.description === "string" ? def.description : undefined;
3191
3684
 
3192
- const typeName = typeof def.typeName === "string" ? def.typeName : undefined;
3685
+ const typeName =
3686
+ typeof def.typeName === "string" ? def.typeName : undefined;
3193
3687
 
3194
3688
  // Extract type
3195
3689
  const typeMap: Record<string, string> = {
3196
- ZodString: 'string',
3197
- ZodNumber: 'number',
3198
- ZodBoolean: 'boolean',
3199
- ZodArray: 'array',
3200
- ZodObject: 'object',
3201
- ZodEnum: 'enum',
3202
- ZodLiteral: 'literal',
3203
- ZodUnion: 'union',
3204
- ZodAny: 'any',
3205
- ZodUnknown: 'unknown',
3690
+ ZodString: "string",
3691
+ ZodNumber: "number",
3692
+ ZodBoolean: "boolean",
3693
+ ZodArray: "array",
3694
+ ZodObject: "object",
3695
+ ZodEnum: "enum",
3696
+ ZodLiteral: "literal",
3697
+ ZodUnion: "union",
3698
+ ZodAny: "any",
3699
+ ZodUnknown: "unknown",
3206
3700
  };
3207
- info.type = typeName ? typeMap[typeName] || typeName.replace('Zod', '').toLowerCase() : undefined;
3701
+ info.type = typeName
3702
+ ? typeMap[typeName] || typeName.replace("Zod", "").toLowerCase()
3703
+ : undefined;
3208
3704
 
3209
3705
  // Extract enum values
3210
- if (typeName === 'ZodEnum' && Array.isArray(def.values)) {
3706
+ if (typeName === "ZodEnum" && Array.isArray(def.values)) {
3211
3707
  info.enum = def.values as unknown[];
3212
- } else if (typeName === 'ZodLiteral' && def.value !== undefined) {
3708
+ } else if (typeName === "ZodLiteral" && def.value !== undefined) {
3213
3709
  info.enum = [def.value];
3214
3710
  }
3215
3711
 
@@ -3230,13 +3726,19 @@ export class WebInspectorElement extends LitElement {
3230
3726
 
3231
3727
  if (contextEntries.length === 0) {
3232
3728
  return html`
3233
- <div class="flex h-full items-center justify-center px-4 py-8 text-center">
3729
+ <div
3730
+ class="flex h-full items-center justify-center px-4 py-8 text-center"
3731
+ >
3234
3732
  <div class="max-w-md">
3235
- <div class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8">
3733
+ <div
3734
+ class="mb-3 flex justify-center text-gray-300 [&>svg]:!h-8 [&>svg]:!w-8"
3735
+ >
3236
3736
  ${this.renderIcon("FileText")}
3237
3737
  </div>
3238
3738
  <p class="text-sm text-gray-600">No context available</p>
3239
- <p class="mt-2 text-xs text-gray-500">Context will appear here once added to CopilotKit.</p>
3739
+ <p class="mt-2 text-xs text-gray-500">
3740
+ Context will appear here once added to CopilotKit.
3741
+ </p>
3240
3742
  </div>
3241
3743
  </div>
3242
3744
  `;
@@ -3246,14 +3748,19 @@ export class WebInspectorElement extends LitElement {
3246
3748
  <div class="flex h-full flex-col overflow-hidden">
3247
3749
  <div class="overflow-auto p-4">
3248
3750
  <div class="space-y-3">
3249
- ${contextEntries.map(([id, context]) => this.renderContextCard(id, context))}
3751
+ ${contextEntries.map(([id, context]) =>
3752
+ this.renderContextCard(id, context),
3753
+ )}
3250
3754
  </div>
3251
3755
  </div>
3252
3756
  </div>
3253
3757
  `;
3254
3758
  }
3255
3759
 
3256
- private renderContextCard(id: string, context: { description?: string; value: unknown }) {
3760
+ private renderContextCard(
3761
+ id: string,
3762
+ context: { description?: string; value: unknown },
3763
+ ) {
3257
3764
  const isExpanded = this.expandedContextItems.has(id);
3258
3765
  const valuePreview = this.getContextValuePreview(context.value);
3259
3766
  const hasValue = context.value !== undefined && context.value !== null;
@@ -3270,7 +3777,11 @@ export class WebInspectorElement extends LitElement {
3270
3777
  <div class="flex-1 min-w-0">
3271
3778
  <p class="text-sm font-medium text-gray-900 mb-1">${title}</p>
3272
3779
  <div class="flex items-center gap-2 text-xs text-gray-500">
3273
- <span class="font-mono truncate inline-block align-middle" style="max-width: 180px;">${id}</span>
3780
+ <span
3781
+ class="font-mono truncate inline-block align-middle"
3782
+ style="max-width: 180px;"
3783
+ >${id}</span
3784
+ >
3274
3785
  ${hasValue
3275
3786
  ? html`
3276
3787
  <span class="text-gray-300">•</span>
@@ -3279,7 +3790,11 @@ export class WebInspectorElement extends LitElement {
3279
3790
  : nothing}
3280
3791
  </div>
3281
3792
  </div>
3282
- <span class="shrink-0 text-gray-400 transition ${isExpanded ? 'rotate-180' : ''}">
3793
+ <span
3794
+ class="shrink-0 text-gray-400 transition ${isExpanded
3795
+ ? "rotate-180"
3796
+ : ""}"
3797
+ >
3283
3798
  ${this.renderIcon("ChevronDown")}
3284
3799
  </span>
3285
3800
  </div>
@@ -3290,12 +3805,17 @@ export class WebInspectorElement extends LitElement {
3290
3805
  <div class="border-t border-gray-200 bg-gray-50/50 px-4 py-3">
3291
3806
  <div class="mb-3">
3292
3807
  <h5 class="mb-1 text-xs font-semibold text-gray-700">ID</h5>
3293
- <code class="block rounded bg-white border border-gray-200 px-2 py-1 text-[10px] font-mono text-gray-600">${id}</code>
3808
+ <code
3809
+ class="block rounded bg-white border border-gray-200 px-2 py-1 text-[10px] font-mono text-gray-600"
3810
+ >${id}</code
3811
+ >
3294
3812
  </div>
3295
3813
  ${hasValue
3296
3814
  ? html`
3297
3815
  <div class="mb-2 flex items-center justify-between gap-2">
3298
- <h5 class="text-xs font-semibold text-gray-700">Value</h5>
3816
+ <h5 class="text-xs font-semibold text-gray-700">
3817
+ Value
3818
+ </h5>
3299
3819
  <button
3300
3820
  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"
3301
3821
  type="button"
@@ -3304,15 +3824,25 @@ export class WebInspectorElement extends LitElement {
3304
3824
  void this.copyContextValue(context.value, id);
3305
3825
  }}
3306
3826
  >
3307
- ${this.copiedContextItems.has(id) ? "Copied" : "Copy JSON"}
3827
+ ${this.copiedContextItems.has(id)
3828
+ ? "Copied"
3829
+ : "Copy JSON"}
3308
3830
  </button>
3309
3831
  </div>
3310
- <div class="rounded-md border border-gray-200 bg-white p-3">
3311
- <pre class="overflow-auto text-xs text-gray-800 max-h-96"><code>${this.formatContextValue(context.value)}</code></pre>
3832
+ <div
3833
+ class="rounded-md border border-gray-200 bg-white p-3"
3834
+ >
3835
+ <pre
3836
+ class="overflow-auto text-xs text-gray-800 max-h-96"
3837
+ ><code>${this.formatContextValue(
3838
+ context.value,
3839
+ )}</code></pre>
3312
3840
  </div>
3313
3841
  `
3314
3842
  : html`
3315
- <div class="flex items-center justify-center py-4 text-xs text-gray-500">
3843
+ <div
3844
+ class="flex items-center justify-center py-4 text-xs text-gray-500"
3845
+ >
3316
3846
  <span>No value available</span>
3317
3847
  </div>
3318
3848
  `}
@@ -3325,14 +3855,14 @@ export class WebInspectorElement extends LitElement {
3325
3855
 
3326
3856
  private getContextValuePreview(value: unknown): string {
3327
3857
  if (value === undefined || value === null) {
3328
- return '';
3858
+ return "";
3329
3859
  }
3330
3860
 
3331
- if (typeof value === 'string') {
3861
+ if (typeof value === "string") {
3332
3862
  return value.length > 50 ? `${value.substring(0, 50)}...` : value;
3333
3863
  }
3334
3864
 
3335
- if (typeof value === 'number' || typeof value === 'boolean') {
3865
+ if (typeof value === "number" || typeof value === "boolean") {
3336
3866
  return String(value);
3337
3867
  }
3338
3868
 
@@ -3340,13 +3870,13 @@ export class WebInspectorElement extends LitElement {
3340
3870
  return `Array(${value.length})`;
3341
3871
  }
3342
3872
 
3343
- if (typeof value === 'object') {
3873
+ if (typeof value === "object") {
3344
3874
  const keys = Object.keys(value);
3345
- return `Object with ${keys.length} key${keys.length !== 1 ? 's' : ''}`;
3875
+ return `Object with ${keys.length} key${keys.length !== 1 ? "s" : ""}`;
3346
3876
  }
3347
3877
 
3348
- if (typeof value === 'function') {
3349
- return 'Function';
3878
+ if (typeof value === "function") {
3879
+ return "Function";
3350
3880
  }
3351
3881
 
3352
3882
  return String(value);
@@ -3354,14 +3884,14 @@ export class WebInspectorElement extends LitElement {
3354
3884
 
3355
3885
  private formatContextValue(value: unknown): string {
3356
3886
  if (value === undefined) {
3357
- return 'undefined';
3887
+ return "undefined";
3358
3888
  }
3359
3889
 
3360
3890
  if (value === null) {
3361
- return 'null';
3891
+ return "null";
3362
3892
  }
3363
3893
 
3364
- if (typeof value === 'function') {
3894
+ if (typeof value === "function") {
3365
3895
  return value.toString();
3366
3896
  }
3367
3897
 
@@ -3372,7 +3902,10 @@ export class WebInspectorElement extends LitElement {
3372
3902
  }
3373
3903
  }
3374
3904
 
3375
- private async copyContextValue(value: unknown, contextId: string): Promise<void> {
3905
+ private async copyContextValue(
3906
+ value: unknown,
3907
+ contextId: string,
3908
+ ): Promise<void> {
3376
3909
  if (typeof navigator === "undefined" || !navigator.clipboard?.writeText) {
3377
3910
  console.warn("Clipboard API is not available in this environment.");
3378
3911
  return;
@@ -3407,7 +3940,10 @@ export class WebInspectorElement extends LitElement {
3407
3940
  }
3408
3941
 
3409
3942
  const clickedDropdown = event.composedPath().some((node) => {
3410
- return node instanceof HTMLElement && node.dataset?.contextDropdownRoot === "true";
3943
+ return (
3944
+ node instanceof HTMLElement &&
3945
+ node.dataset?.contextDropdownRoot === "true"
3946
+ );
3411
3947
  });
3412
3948
 
3413
3949
  if (!clickedDropdown) {
@@ -3444,9 +3980,13 @@ export class WebInspectorElement extends LitElement {
3444
3980
  }
3445
3981
 
3446
3982
  if (!this.announcementLoaded && !this.announcementMarkdown) {
3447
- return html`<div 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)]">
3983
+ return html`<div
3984
+ 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)]"
3985
+ >
3448
3986
  <div class="flex items-center gap-2 font-semibold">
3449
- <span class="inline-flex h-6 w-6 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm">
3987
+ <span
3988
+ class="inline-flex h-6 w-6 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm"
3989
+ >
3450
3990
  ${this.renderIcon("Megaphone")}
3451
3991
  </span>
3452
3992
  <span>Loading latest announcement…</span>
@@ -3455,14 +3995,21 @@ export class WebInspectorElement extends LitElement {
3455
3995
  }
3456
3996
 
3457
3997
  if (this.announcementLoadError) {
3458
- return html`<div 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)]">
3998
+ return html`<div
3999
+ 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)]"
4000
+ >
3459
4001
  <div class="flex items-center gap-2 font-semibold">
3460
- <span class="inline-flex h-6 w-6 items-center justify-center rounded-md bg-rose-600 text-white shadow-sm">
4002
+ <span
4003
+ class="inline-flex h-6 w-6 items-center justify-center rounded-md bg-rose-600 text-white shadow-sm"
4004
+ >
3461
4005
  ${this.renderIcon("Megaphone")}
3462
4006
  </span>
3463
4007
  <span>Announcement unavailable</span>
3464
4008
  </div>
3465
- <p class="mt-2 text-xs text-rose-800">We couldn’t load the latest notice. Please try opening the inspector again.</p>
4009
+ <p class="mt-2 text-xs text-rose-800">
4010
+ We couldn’t load the latest notice. Please try opening the inspector
4011
+ again.
4012
+ </p>
3466
4013
  </div>`;
3467
4014
  }
3468
4015
 
@@ -3472,35 +4019,59 @@ export class WebInspectorElement extends LitElement {
3472
4019
 
3473
4020
  const content = this.announcementHtml
3474
4021
  ? unsafeHTML(this.announcementHtml)
3475
- : html`<pre class="whitespace-pre-wrap text-sm text-gray-900">${this.announcementMarkdown}</pre>`;
4022
+ : html`<pre class="whitespace-pre-wrap text-sm text-gray-900">
4023
+ ${this.announcementMarkdown}</pre
4024
+ >`;
3476
4025
 
3477
- return html`<div 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)]">
3478
- <div class="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-900">
3479
- <span class="inline-flex h-7 w-7 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm">
4026
+ return html`<div
4027
+ 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)]"
4028
+ >
4029
+ <div
4030
+ class="mb-3 flex items-center gap-2 text-sm font-semibold text-slate-900"
4031
+ >
4032
+ <span
4033
+ class="inline-flex h-7 w-7 items-center justify-center rounded-md bg-slate-900 text-white shadow-sm"
4034
+ >
3480
4035
  ${this.renderIcon("Megaphone")}
3481
4036
  </span>
3482
4037
  <span>Announcement</span>
3483
- <button class="announcement-dismiss ml-auto" type="button" @click=${this.handleDismissAnnouncement} aria-label="Dismiss announcement">
4038
+ <button
4039
+ class="announcement-dismiss ml-auto"
4040
+ type="button"
4041
+ @click=${this.handleDismissAnnouncement}
4042
+ aria-label="Dismiss announcement"
4043
+ >
3484
4044
  Dismiss
3485
4045
  </button>
3486
4046
  </div>
3487
- <div class="announcement-content text-sm leading-relaxed text-gray-900">${content}</div>
4047
+ <div class="announcement-content text-sm leading-relaxed text-gray-900">
4048
+ ${content}
4049
+ </div>
3488
4050
  </div>`;
3489
4051
  }
3490
4052
 
3491
4053
  private ensureAnnouncementLoading(): void {
3492
- if (this.announcementPromise || typeof window === "undefined" || typeof fetch === "undefined") {
4054
+ if (
4055
+ this.announcementPromise ||
4056
+ typeof window === "undefined" ||
4057
+ typeof fetch === "undefined"
4058
+ ) {
3493
4059
  return;
3494
4060
  }
3495
4061
  this.announcementPromise = this.fetchAnnouncement();
3496
4062
  }
3497
4063
 
3498
4064
  private renderAnnouncementPreview() {
3499
- if (!this.hasUnseenAnnouncement || !this.showAnnouncementPreview || !this.announcementPreviewText) {
4065
+ if (
4066
+ !this.hasUnseenAnnouncement ||
4067
+ !this.showAnnouncementPreview ||
4068
+ !this.announcementPreviewText
4069
+ ) {
3500
4070
  return nothing;
3501
4071
  }
3502
4072
 
3503
- const side = this.contextState.button.anchor.horizontal === "left" ? "right" : "left";
4073
+ const side =
4074
+ this.contextState.button.anchor.horizontal === "left" ? "right" : "left";
3504
4075
 
3505
4076
  return html`<div
3506
4077
  class="announcement-preview"
@@ -3535,9 +4106,12 @@ export class WebInspectorElement extends LitElement {
3535
4106
  announcement?: unknown;
3536
4107
  };
3537
4108
 
3538
- const timestamp = typeof data?.timestamp === "string" ? data.timestamp : null;
3539
- const previewText = typeof data?.previewText === "string" ? data.previewText : null;
3540
- const markdown = typeof data?.announcement === "string" ? data.announcement : null;
4109
+ const timestamp =
4110
+ typeof data?.timestamp === "string" ? data.timestamp : null;
4111
+ const previewText =
4112
+ typeof data?.previewText === "string" ? data.previewText : null;
4113
+ const markdown =
4114
+ typeof data?.announcement === "string" ? data.announcement : null;
3541
4115
 
3542
4116
  if (!timestamp || !markdown) {
3543
4117
  throw new Error("Malformed announcement payload");
@@ -3548,7 +4122,9 @@ export class WebInspectorElement extends LitElement {
3548
4122
  this.announcementTimestamp = timestamp;
3549
4123
  this.announcementPreviewText = previewText ?? "";
3550
4124
  this.announcementMarkdown = markdown;
3551
- this.hasUnseenAnnouncement = (!storedTimestamp || storedTimestamp !== timestamp) && !!this.announcementPreviewText;
4125
+ this.hasUnseenAnnouncement =
4126
+ (!storedTimestamp || storedTimestamp !== timestamp) &&
4127
+ !!this.announcementPreviewText;
3552
4128
  this.showAnnouncementPreview = this.hasUnseenAnnouncement;
3553
4129
  this.announcementHtml = await this.convertMarkdownToHtml(markdown);
3554
4130
  this.announcementLoaded = true;
@@ -3561,7 +4137,9 @@ export class WebInspectorElement extends LitElement {
3561
4137
  }
3562
4138
  }
3563
4139
 
3564
- private async convertMarkdownToHtml(markdown: string): Promise<string | null> {
4140
+ private async convertMarkdownToHtml(
4141
+ markdown: string,
4142
+ ): Promise<string | null> {
3565
4143
  const renderer = new marked.Renderer();
3566
4144
  renderer.link = (href, title, text) => {
3567
4145
  const safeHref = this.escapeHtmlAttr(this.appendRefParam(href ?? ""));
@@ -3573,7 +4151,12 @@ export class WebInspectorElement extends LitElement {
3573
4151
 
3574
4152
  private appendRefParam(href: string): string {
3575
4153
  try {
3576
- const url = new URL(href, typeof window !== "undefined" ? window.location.href : "https://copilotkit.ai");
4154
+ const url = new URL(
4155
+ href,
4156
+ typeof window !== "undefined"
4157
+ ? window.location.href
4158
+ : "https://copilotkit.ai",
4159
+ );
3577
4160
  if (!url.searchParams.has("ref")) {
3578
4161
  url.searchParams.append("ref", "cpk-inspector");
3579
4162
  }
@@ -3633,7 +4216,9 @@ export class WebInspectorElement extends LitElement {
3633
4216
  if (!this.announcementTimestamp) {
3634
4217
  // If still loading, attempt once more after promise resolves; avoid infinite requeues
3635
4218
  if (this.announcementPromise && !this.announcementLoaded) {
3636
- void this.announcementPromise.then(() => this.markAnnouncementSeen()).catch(() => undefined);
4219
+ void this.announcementPromise
4220
+ .then(() => this.markAnnouncementSeen())
4221
+ .catch(() => undefined);
3637
4222
  }
3638
4223
  this.requestUpdate();
3639
4224
  return;