@skippr/live-agent-sdk 0.25.0 → 0.27.0

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.
@@ -283,36 +283,6 @@ function useSession({ agentId, authToken, appKey, userToken }) {
283
283
  pendingScreenStream
284
284
  };
285
285
  }
286
-
287
- // src/components/AutoStartMedia.tsx
288
- import { useConnectionState, useLocalParticipant } from "@livekit/components-react";
289
- import { ConnectionState, Track } from "livekit-client";
290
- import { useEffect as useEffect3, useRef } from "react";
291
- function AutoStartMedia({ pendingScreenStream }) {
292
- const { localParticipant } = useLocalParticipant();
293
- const connectionState = useConnectionState();
294
- const didStartRef = useRef(false);
295
- useEffect3(() => {
296
- if (didStartRef.current)
297
- return;
298
- if (connectionState !== ConnectionState.Connected)
299
- return;
300
- didStartRef.current = true;
301
- localParticipant.setMicrophoneEnabled(true).catch((error) => console.error("Failed to enable microphone:", error));
302
- if (pendingScreenStream) {
303
- const videoTrack = pendingScreenStream.getVideoTracks()[0];
304
- if (videoTrack) {
305
- videoTrack.contentHint = "detail";
306
- localParticipant.publishTrack(videoTrack, { source: Track.Source.ScreenShare }).catch((error) => {
307
- console.error("Failed to publish screen share track:", error);
308
- for (const track of pendingScreenStream.getTracks())
309
- track.stop();
310
- });
311
- }
312
- }
313
- }, [connectionState, localParticipant, pendingScreenStream]);
314
- return null;
315
- }
316
286
  // ../../node_modules/.bun/lucide-react@1.8.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/createLucideIcon.js
317
287
  import { forwardRef as forwardRef2, createElement as createElement3 } from "react";
318
288
 
@@ -542,9 +512,6 @@ var __iconNode16 = [
542
512
  ["path", { d: "m21.854 2.147-10.94 10.939", key: "12cjpa" }]
543
513
  ];
544
514
  var Send = createLucideIcon("send", __iconNode16);
545
- // src/components/MinimizedBubble.tsx
546
- import { useEffect as useEffect4 } from "react";
547
-
548
515
  // src/hooks/useAgentVoiceState.ts
549
516
  import { useVoiceAssistant } from "@livekit/components-react";
550
517
  function useAgentVoiceState() {
@@ -568,7 +535,7 @@ function useLiveAgent() {
568
535
  }
569
536
 
570
537
  // src/hooks/useMediaControls.ts
571
- import { useLocalParticipant as useLocalParticipant2 } from "@livekit/components-react";
538
+ import { useLocalParticipant } from "@livekit/components-react";
572
539
  import { ScreenSharePresets } from "livekit-client";
573
540
  import { useCallback as useCallback3 } from "react";
574
541
  var SCREEN_SHARE_OPTIONS = {
@@ -577,7 +544,7 @@ var SCREEN_SHARE_OPTIONS = {
577
544
  contentHint: "detail"
578
545
  };
579
546
  function useMediaControls() {
580
- const { localParticipant } = useLocalParticipant2();
547
+ const { localParticipant } = useLocalParticipant();
581
548
  const isMuted = !localParticipant.isMicrophoneEnabled;
582
549
  const isScreenSharing = localParticipant.isScreenShareEnabled;
583
550
  const toggleMute = useCallback3(async () => {
@@ -597,11 +564,155 @@ function useMediaControls() {
597
564
  return { isMuted, toggleMute, isScreenSharing, toggleScreenShare };
598
565
  }
599
566
 
600
- // src/assets/logo-icon.png
601
- var logo_icon_default = "./logo-icon-cn8fyke6.png";
567
+ // src/components/AgentStateBanner.tsx
568
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
569
+ function AgentStateBanner() {
570
+ const { isConnected } = useLiveAgent();
571
+ const { isScreenSharing } = useMediaControls();
572
+ const { state } = useAgentVoiceState();
573
+ if (!isConnected)
574
+ return null;
575
+ return /* @__PURE__ */ jsx("div", {
576
+ className: "skippr:fixed skippr:top-0 skippr:left-0 skippr:right-0 skippr:z-[2147483647] skippr:flex skippr:justify-center skippr:pointer-events-none",
577
+ children: /* @__PURE__ */ jsx("div", {
578
+ className: "skippr:pointer-events-auto skippr:flex skippr:items-center skippr:gap-2 skippr:bg-indigo-500/95 skippr:backdrop-blur-sm skippr:text-white skippr:text-xs skippr:font-medium skippr:px-4 skippr:py-1.5 skippr:rounded-b-lg skippr:shadow-lg",
579
+ children: /* @__PURE__ */ jsx(BannerContent, {
580
+ state,
581
+ isScreenSharing
582
+ })
583
+ })
584
+ });
585
+ }
586
+ function BannerContent({
587
+ state,
588
+ isScreenSharing
589
+ }) {
590
+ if (state === "speaking") {
591
+ return /* @__PURE__ */ jsxs(Fragment, {
592
+ children: [
593
+ /* @__PURE__ */ jsx(SpeakingBars, {}),
594
+ /* @__PURE__ */ jsx("span", {
595
+ children: "Skippr is talking"
596
+ })
597
+ ]
598
+ });
599
+ }
600
+ if (state === "thinking") {
601
+ return /* @__PURE__ */ jsxs(Fragment, {
602
+ children: [
603
+ /* @__PURE__ */ jsx(ThinkingDots, {}),
604
+ /* @__PURE__ */ jsx("span", {
605
+ children: "Skippr is thinking"
606
+ })
607
+ ]
608
+ });
609
+ }
610
+ if (state === "listening" && isScreenSharing) {
611
+ return /* @__PURE__ */ jsxs(Fragment, {
612
+ children: [
613
+ /* @__PURE__ */ jsx(ObservingDot, {}),
614
+ /* @__PURE__ */ jsx(Eye, {
615
+ className: "skippr:size-3.5"
616
+ }),
617
+ /* @__PURE__ */ jsx("span", {
618
+ children: "Skippr is observing this page"
619
+ })
620
+ ]
621
+ });
622
+ }
623
+ return /* @__PURE__ */ jsxs(Fragment, {
624
+ children: [
625
+ /* @__PURE__ */ jsx(ObservingDot, {}),
626
+ /* @__PURE__ */ jsx("span", {
627
+ children: "Skippr is connected"
628
+ })
629
+ ]
630
+ });
631
+ }
632
+ function ObservingDot() {
633
+ return /* @__PURE__ */ jsxs("span", {
634
+ className: "skippr:relative skippr:flex skippr:size-1.5",
635
+ children: [
636
+ /* @__PURE__ */ jsx("span", {
637
+ className: "skippr:absolute skippr:inline-flex skippr:size-full skippr:animate-ping skippr:rounded-full skippr:bg-emerald-400 skippr:opacity-75"
638
+ }),
639
+ /* @__PURE__ */ jsx("span", {
640
+ className: "skippr:relative skippr:inline-flex skippr:size-1.5 skippr:rounded-full skippr:bg-emerald-400"
641
+ })
642
+ ]
643
+ });
644
+ }
645
+ function ThinkingDots() {
646
+ return /* @__PURE__ */ jsxs("span", {
647
+ className: "skippr:flex skippr:items-center skippr:gap-[3px]",
648
+ children: [
649
+ /* @__PURE__ */ jsx("span", {
650
+ className: "skippr:size-1 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:0ms]"
651
+ }),
652
+ /* @__PURE__ */ jsx("span", {
653
+ className: "skippr:size-1 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:150ms]"
654
+ }),
655
+ /* @__PURE__ */ jsx("span", {
656
+ className: "skippr:size-1 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:300ms]"
657
+ })
658
+ ]
659
+ });
660
+ }
661
+ function SpeakingBars() {
662
+ return /* @__PURE__ */ jsxs("span", {
663
+ className: "skippr:flex skippr:items-center skippr:gap-[2px] skippr:h-3.5",
664
+ children: [
665
+ /* @__PURE__ */ jsx("span", {
666
+ className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_infinite] skippr:h-1.5"
667
+ }),
668
+ /* @__PURE__ */ jsx("span", {
669
+ className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.15s_infinite] skippr:h-3"
670
+ }),
671
+ /* @__PURE__ */ jsx("span", {
672
+ className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.3s_infinite] skippr:h-2"
673
+ }),
674
+ /* @__PURE__ */ jsx("span", {
675
+ className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.45s_infinite] skippr:h-3.5"
676
+ }),
677
+ /* @__PURE__ */ jsx("span", {
678
+ className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.6s_infinite] skippr:h-1"
679
+ })
680
+ ]
681
+ });
682
+ }
602
683
 
603
- // src/lib/assets.ts
604
- var LOGO_URL = logo_icon_default;
684
+ // src/components/AutoStartMedia.tsx
685
+ import { useConnectionState, useLocalParticipant as useLocalParticipant2 } from "@livekit/components-react";
686
+ import { ConnectionState, Track } from "livekit-client";
687
+ import { useEffect as useEffect3, useRef } from "react";
688
+ function AutoStartMedia({ pendingScreenStream }) {
689
+ const { localParticipant } = useLocalParticipant2();
690
+ const connectionState = useConnectionState();
691
+ const didStartRef = useRef(false);
692
+ useEffect3(() => {
693
+ if (didStartRef.current)
694
+ return;
695
+ if (connectionState !== ConnectionState.Connected)
696
+ return;
697
+ didStartRef.current = true;
698
+ localParticipant.setMicrophoneEnabled(true).catch((error) => console.error("Failed to enable microphone:", error));
699
+ if (pendingScreenStream) {
700
+ const videoTrack = pendingScreenStream.getVideoTracks()[0];
701
+ if (videoTrack) {
702
+ videoTrack.contentHint = "detail";
703
+ localParticipant.publishTrack(videoTrack, { source: Track.Source.ScreenShare }).catch((error) => {
704
+ console.error("Failed to publish screen share track:", error);
705
+ for (const track of pendingScreenStream.getTracks())
706
+ track.stop();
707
+ });
708
+ }
709
+ }
710
+ }, [connectionState, localParticipant, pendingScreenStream]);
711
+ return null;
712
+ }
713
+
714
+ // src/components/MinimizedBubble.tsx
715
+ import { useEffect as useEffect4 } from "react";
605
716
 
606
717
  // src/lib/utils.ts
607
718
  import { clsx } from "clsx";
@@ -610,19 +721,101 @@ function cn(...inputs) {
610
721
  return twMerge(clsx(inputs));
611
722
  }
612
723
 
724
+ // src/components/Logo.tsx
725
+ import { useId } from "react";
726
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
727
+ function Logo({ className }) {
728
+ const reactId = useId().replace(/:/g, "");
729
+ const clipId = `skippr-logo-clip-${reactId}`;
730
+ const gradientId = `skippr-logo-gradient-${reactId}`;
731
+ return /* @__PURE__ */ jsxs2("svg", {
732
+ width: "1em",
733
+ height: "1em",
734
+ viewBox: "0 0 30 30",
735
+ fill: "none",
736
+ xmlns: "http://www.w3.org/2000/svg",
737
+ role: "img",
738
+ "aria-label": "Skippr",
739
+ className,
740
+ children: [
741
+ /* @__PURE__ */ jsxs2("g", {
742
+ clipPath: `url(#${clipId})`,
743
+ children: [
744
+ /* @__PURE__ */ jsx2("path", {
745
+ d: "M0 10C0 4.47715 4.47715 0 10 0H20C25.5228 0 30 4.47715 30 10V20C30 25.5228 25.5228 30 20 30H10C4.47715 30 0 25.5228 0 20V10Z",
746
+ fill: "#2D2D3F"
747
+ }),
748
+ /* @__PURE__ */ jsx2("rect", {
749
+ x: "7.83325",
750
+ y: "14.9404",
751
+ width: "12.4083",
752
+ height: "4.72833",
753
+ rx: "2.36417",
754
+ transform: "rotate(-45 7.83325 14.9404)",
755
+ fill: "#52FFF9"
756
+ }),
757
+ /* @__PURE__ */ jsx2("path", {
758
+ d: "M18.8975 12.5928C20.2728 12.5928 21.3877 13.647 21.3877 14.9474C21.3877 16.2479 20.2728 17.3021 18.8975 17.3021L11.4269 17.3021C10.0516 17.3021 8.93665 16.2479 8.93665 14.9474C8.93665 13.647 10.0516 12.5928 11.4269 12.5928L18.8975 12.5928Z",
759
+ fill: `url(#${gradientId})`
760
+ }),
761
+ /* @__PURE__ */ jsx2("rect", {
762
+ x: "10.1665",
763
+ y: "20.4404",
764
+ width: "12.4083",
765
+ height: "4.72833",
766
+ rx: "2.36417",
767
+ transform: "rotate(-45 10.1665 20.4404)",
768
+ fill: "white"
769
+ })
770
+ ]
771
+ }),
772
+ /* @__PURE__ */ jsxs2("defs", {
773
+ children: [
774
+ /* @__PURE__ */ jsxs2("linearGradient", {
775
+ id: gradientId,
776
+ x1: "18.9237",
777
+ y1: "16.9997",
778
+ x2: "11.4129",
779
+ y2: "14.1904",
780
+ gradientUnits: "userSpaceOnUse",
781
+ children: [
782
+ /* @__PURE__ */ jsx2("stop", {
783
+ offset: "0.473958",
784
+ stopColor: "white"
785
+ }),
786
+ /* @__PURE__ */ jsx2("stop", {
787
+ offset: "1",
788
+ stopColor: "#52FFF9"
789
+ })
790
+ ]
791
+ }),
792
+ /* @__PURE__ */ jsx2("clipPath", {
793
+ id: clipId,
794
+ children: /* @__PURE__ */ jsx2("rect", {
795
+ width: "30",
796
+ height: "30",
797
+ fill: "white"
798
+ })
799
+ })
800
+ ]
801
+ })
802
+ ]
803
+ });
804
+ }
805
+
613
806
  // src/components/ui/tooltip.tsx
614
- import { jsx, jsxs } from "react/jsx-runtime";
807
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
615
808
  var ALIGN_CLASSES = {
616
809
  center: "skippr:left-1/2 skippr:-translate-x-1/2",
617
810
  start: "skippr:left-0",
618
811
  end: "skippr:right-0"
619
812
  };
620
813
  function Tooltip({ label, children, position = "top", align = "center" }) {
621
- return /* @__PURE__ */ jsxs("span", {
814
+ return /* @__PURE__ */ jsxs3("span", {
622
815
  className: "skippr:relative skippr:inline-flex skippr:group",
623
816
  children: [
624
817
  children,
625
- /* @__PURE__ */ jsx("span", {
818
+ /* @__PURE__ */ jsx3("span", {
626
819
  className: cn("skippr:pointer-events-none skippr:absolute skippr:z-10", "skippr:whitespace-nowrap skippr:rounded-md skippr:bg-foreground skippr:px-2 skippr:py-1", "skippr:text-[11px] skippr:text-background skippr:font-medium", "skippr:opacity-0 skippr:scale-95 skippr:transition-all skippr:duration-150", "skippr:group-hover:opacity-100 skippr:group-hover:scale-100", "skippr:group-focus-within:opacity-100 skippr:group-focus-within:scale-100", ALIGN_CLASSES[align], position === "top" && "skippr:bottom-full skippr:mb-1.5", position === "bottom" && "skippr:top-full skippr:mt-1.5"),
627
820
  "aria-hidden": "true",
628
821
  children: label
@@ -632,113 +825,67 @@ function Tooltip({ label, children, position = "top", align = "center" }) {
632
825
  }
633
826
 
634
827
  // src/components/MinimizedBubble.tsx
635
- import { jsx as jsx2, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
828
+ import { jsx as jsx4, jsxs as jsxs4, Fragment as Fragment2 } from "react/jsx-runtime";
636
829
  var BUBBLE_BUTTON = "skippr:flex skippr:size-12 skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:rounded-[14px] skippr:shadow-[0_4px_16px_rgba(45,43,61,0.45),0_2px_4px_rgba(0,0,0,0.1)] skippr:transition-all skippr:hover:-translate-y-0.5 skippr:active:translate-y-0";
637
- function AgentBubbleContent({ agentState }) {
638
- if (agentState === "speaking") {
639
- return /* @__PURE__ */ jsxs2("div", {
640
- className: "skippr:flex skippr:h-5 skippr:items-center skippr:justify-center skippr:gap-[3px]",
641
- children: [
642
- /* @__PURE__ */ jsx2("span", {
643
- className: "skippr:w-[3px] skippr:h-2 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_infinite]"
644
- }),
645
- /* @__PURE__ */ jsx2("span", {
646
- className: "skippr:w-[3px] skippr:h-3.5 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.15s_infinite]"
647
- }),
648
- /* @__PURE__ */ jsx2("span", {
649
- className: "skippr:w-[3px] skippr:h-2.5 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.3s_infinite]"
650
- }),
651
- /* @__PURE__ */ jsx2("span", {
652
- className: "skippr:w-[3px] skippr:h-4 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.45s_infinite]"
653
- }),
654
- /* @__PURE__ */ jsx2("span", {
655
- className: "skippr:w-[3px] skippr:h-1.5 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.6s_infinite]"
656
- })
657
- ]
658
- });
659
- }
660
- if (agentState === "thinking") {
661
- return /* @__PURE__ */ jsxs2("div", {
662
- className: "skippr:flex skippr:items-center skippr:justify-center skippr:gap-[4px]",
663
- children: [
664
- /* @__PURE__ */ jsx2("span", {
665
- className: "skippr:size-1.5 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:0ms]"
666
- }),
667
- /* @__PURE__ */ jsx2("span", {
668
- className: "skippr:size-1.5 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:150ms]"
669
- }),
670
- /* @__PURE__ */ jsx2("span", {
671
- className: "skippr:size-1.5 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:300ms]"
672
- })
673
- ]
674
- });
675
- }
676
- return /* @__PURE__ */ jsx2("img", {
677
- src: LOGO_URL,
678
- alt: "Skippr",
679
- className: "skippr:size-7"
680
- });
681
- }
682
830
  function ConnectedBubbleContent() {
683
831
  const { expandPanel, disconnect, position } = useLiveAgent();
684
- const { state: agentState } = useAgentVoiceState();
685
832
  const { isMuted, toggleMute, isScreenSharing, toggleScreenShare } = useMediaControls();
686
833
  const tooltipAlign = position === "right" ? "end" : "start";
687
- return /* @__PURE__ */ jsxs2(Fragment, {
834
+ return /* @__PURE__ */ jsxs4(Fragment2, {
688
835
  children: [
689
- /* @__PURE__ */ jsx2(Tooltip, {
836
+ /* @__PURE__ */ jsx4(Tooltip, {
690
837
  label: isMuted ? "Unmute" : "Mute",
691
838
  align: tooltipAlign,
692
- children: /* @__PURE__ */ jsx2("button", {
839
+ children: /* @__PURE__ */ jsx4("button", {
693
840
  type: "button",
694
841
  onClick: toggleMute,
695
842
  "aria-label": isMuted ? "Unmute" : "Mute",
696
843
  className: cn(BUBBLE_BUTTON, isMuted ? "skippr:bg-destructive skippr:text-destructive-foreground skippr:hover:bg-destructive/90" : "skippr:bg-white skippr:text-foreground skippr:hover:bg-muted"),
697
- children: isMuted ? /* @__PURE__ */ jsx2(MicOff, {
844
+ children: isMuted ? /* @__PURE__ */ jsx4(MicOff, {
698
845
  className: "skippr:size-5"
699
- }) : /* @__PURE__ */ jsx2(Mic, {
846
+ }) : /* @__PURE__ */ jsx4(Mic, {
700
847
  className: "skippr:size-5"
701
848
  })
702
849
  })
703
850
  }),
704
- /* @__PURE__ */ jsx2(Tooltip, {
851
+ /* @__PURE__ */ jsx4(Tooltip, {
705
852
  label: isScreenSharing ? "Stop sharing" : "Share screen",
706
853
  align: tooltipAlign,
707
- children: /* @__PURE__ */ jsx2("button", {
854
+ children: /* @__PURE__ */ jsx4("button", {
708
855
  type: "button",
709
856
  onClick: toggleScreenShare,
710
857
  "aria-label": isScreenSharing ? "Stop sharing screen" : "Share screen",
711
858
  className: cn(BUBBLE_BUTTON, isScreenSharing ? "skippr:bg-bubble skippr:text-white skippr:hover:brightness-110" : "skippr:bg-white skippr:text-foreground skippr:hover:bg-muted"),
712
- children: isScreenSharing ? /* @__PURE__ */ jsx2(MonitorOff, {
859
+ children: isScreenSharing ? /* @__PURE__ */ jsx4(MonitorOff, {
713
860
  className: "skippr:size-5"
714
- }) : /* @__PURE__ */ jsx2(Monitor, {
861
+ }) : /* @__PURE__ */ jsx4(Monitor, {
715
862
  className: "skippr:size-5"
716
863
  })
717
864
  })
718
865
  }),
719
- /* @__PURE__ */ jsx2(Tooltip, {
866
+ /* @__PURE__ */ jsx4(Tooltip, {
720
867
  label: "End session",
721
868
  align: tooltipAlign,
722
- children: /* @__PURE__ */ jsx2("button", {
869
+ children: /* @__PURE__ */ jsx4("button", {
723
870
  type: "button",
724
871
  onClick: () => disconnect(),
725
872
  "aria-label": "End session",
726
873
  className: cn(BUBBLE_BUTTON, "skippr:bg-destructive skippr:text-destructive-foreground skippr:hover:bg-destructive/90"),
727
- children: /* @__PURE__ */ jsx2(PhoneOff, {
874
+ children: /* @__PURE__ */ jsx4(PhoneOff, {
728
875
  className: "skippr:size-5"
729
876
  })
730
877
  })
731
878
  }),
732
- /* @__PURE__ */ jsx2(Tooltip, {
879
+ /* @__PURE__ */ jsx4(Tooltip, {
733
880
  label: "Open chat & transcript",
734
881
  align: tooltipAlign,
735
- children: /* @__PURE__ */ jsx2("button", {
882
+ children: /* @__PURE__ */ jsx4("button", {
736
883
  type: "button",
737
884
  onClick: expandPanel,
738
885
  "aria-label": "Open chat & transcript",
739
886
  className: cn(BUBBLE_BUTTON, "skippr:bg-bubble skippr:hover:brightness-110"),
740
- children: /* @__PURE__ */ jsx2(AgentBubbleContent, {
741
- agentState
887
+ children: /* @__PURE__ */ jsx4(Logo, {
888
+ className: "skippr:size-7"
742
889
  })
743
890
  })
744
891
  })
@@ -748,21 +895,19 @@ function ConnectedBubbleContent() {
748
895
  function IdleBubbleContent() {
749
896
  const { expandPanel, position } = useLiveAgent();
750
897
  const tooltipAlign = position === "right" ? "end" : "start";
751
- return /* @__PURE__ */ jsx2(Tooltip, {
898
+ return /* @__PURE__ */ jsx4(Tooltip, {
752
899
  label: "Open Skippr assistant",
753
900
  align: tooltipAlign,
754
- children: /* @__PURE__ */ jsxs2("button", {
901
+ children: /* @__PURE__ */ jsxs4("button", {
755
902
  type: "button",
756
903
  onClick: expandPanel,
757
904
  "aria-label": "Skippr assistant",
758
905
  className: cn(BUBBLE_BUTTON, "skippr:relative skippr:bg-bubble skippr:hover:brightness-110"),
759
906
  children: [
760
- /* @__PURE__ */ jsx2("img", {
761
- src: LOGO_URL,
762
- alt: "Skippr",
907
+ /* @__PURE__ */ jsx4(Logo, {
763
908
  className: "skippr:relative skippr:z-10 skippr:size-7"
764
909
  }),
765
- /* @__PURE__ */ jsx2("span", {
910
+ /* @__PURE__ */ jsx4("span", {
766
911
  className: "skippr:absolute skippr:-inset-[3px] skippr:animate-pulse skippr:rounded-[17px] skippr:border-2 skippr:border-bubble/50"
767
912
  })
768
913
  ]
@@ -778,14 +923,14 @@ function WelcomeBubble({
778
923
  const timer = setTimeout(onDismiss, 5000);
779
924
  return () => clearTimeout(timer);
780
925
  }, [onDismiss]);
781
- return /* @__PURE__ */ jsxs2("button", {
926
+ return /* @__PURE__ */ jsxs4("button", {
782
927
  type: "button",
783
928
  className: cn("skippr:absolute skippr:bottom-full skippr:mb-3", "skippr:max-w-64 skippr:rounded-xl skippr:bg-card skippr:shadow-lg", "skippr:border skippr:border-border skippr:px-4 skippr:py-3", "skippr:text-sm skippr:text-foreground skippr:leading-relaxed skippr:text-left", "skippr:animate-[skippr-fade-in_0.3s_ease-out]", "skippr:cursor-pointer", position === "right" ? "skippr:right-0" : "skippr:left-0"),
784
929
  onClick: onDismiss,
785
930
  "aria-label": "Dismiss",
786
931
  children: [
787
932
  message,
788
- /* @__PURE__ */ jsx2("span", {
933
+ /* @__PURE__ */ jsx4("span", {
789
934
  className: cn("skippr:absolute skippr:top-full skippr:size-2.5", "skippr:border-l skippr:border-t skippr:border-border skippr:bg-card", "skippr:rotate-[225deg]", position === "right" ? "skippr:right-5" : "skippr:left-5", "skippr:-mt-[5px]")
790
935
  })
791
936
  ]
@@ -798,53 +943,19 @@ function MinimizedBubble({
798
943
  }) {
799
944
  const { isConnected, isStarting, position } = useLiveAgent();
800
945
  const inSession = isConnected || isStarting;
801
- return /* @__PURE__ */ jsxs2("div", {
946
+ return /* @__PURE__ */ jsxs4("div", {
802
947
  className: cn("skippr:fixed skippr:bottom-6 skippr:z-[9999]", "skippr:flex skippr:items-center skippr:gap-2", position === "right" ? "skippr:right-6" : "skippr:left-6"),
803
948
  children: [
804
- welcomeMessage && !inSession && !welcomeDismissed && /* @__PURE__ */ jsx2(WelcomeBubble, {
949
+ welcomeMessage && !inSession && !welcomeDismissed && /* @__PURE__ */ jsx4(WelcomeBubble, {
805
950
  message: welcomeMessage,
806
951
  position,
807
952
  onDismiss: onDismissWelcome
808
953
  }),
809
- inSession ? /* @__PURE__ */ jsx2(ConnectedBubbleContent, {}) : /* @__PURE__ */ jsx2(IdleBubbleContent, {})
954
+ inSession ? /* @__PURE__ */ jsx4(ConnectedBubbleContent, {}) : /* @__PURE__ */ jsx4(IdleBubbleContent, {})
810
955
  ]
811
956
  });
812
957
  }
813
958
 
814
- // src/components/ObservingBanner.tsx
815
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
816
- function ObservingBanner() {
817
- const { isConnected } = useLiveAgent();
818
- const { isScreenSharing } = useMediaControls();
819
- if (!isConnected || !isScreenSharing)
820
- return null;
821
- return /* @__PURE__ */ jsx3("div", {
822
- className: "skippr:fixed skippr:top-0 skippr:left-0 skippr:right-0 skippr:z-[2147483647] skippr:flex skippr:justify-center skippr:pointer-events-none",
823
- children: /* @__PURE__ */ jsxs3("div", {
824
- className: "skippr:pointer-events-auto skippr:flex skippr:items-center skippr:gap-2 skippr:bg-indigo-500/95 skippr:backdrop-blur-sm skippr:text-white skippr:text-xs skippr:font-medium skippr:px-4 skippr:py-1.5 skippr:rounded-b-lg skippr:shadow-lg",
825
- children: [
826
- /* @__PURE__ */ jsxs3("span", {
827
- className: "skippr:relative skippr:flex skippr:size-1.5",
828
- children: [
829
- /* @__PURE__ */ jsx3("span", {
830
- className: "skippr:absolute skippr:inline-flex skippr:size-full skippr:animate-ping skippr:rounded-full skippr:bg-emerald-400 skippr:opacity-75"
831
- }),
832
- /* @__PURE__ */ jsx3("span", {
833
- className: "skippr:relative skippr:inline-flex skippr:size-1.5 skippr:rounded-full skippr:bg-emerald-400"
834
- })
835
- ]
836
- }),
837
- /* @__PURE__ */ jsx3(Eye, {
838
- className: "skippr:size-3.5"
839
- }),
840
- /* @__PURE__ */ jsx3("span", {
841
- children: "Skippr is observing this page"
842
- })
843
- ]
844
- })
845
- });
846
- }
847
-
848
959
  // src/components/Sidebar.tsx
849
960
  import { useEffect as useEffect11 } from "react";
850
961
 
@@ -1045,50 +1156,50 @@ function useElapsedSeconds(isRunning) {
1045
1156
  }
1046
1157
 
1047
1158
  // src/components/ChatHeader.tsx
1048
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1159
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1049
1160
  function ChatHeader() {
1050
1161
  const { isConnected, minimizePanel, minimizable } = useLiveAgent();
1051
1162
  const elapsed = useElapsedSeconds(isConnected);
1052
- return /* @__PURE__ */ jsxs4("header", {
1163
+ return /* @__PURE__ */ jsxs5("header", {
1053
1164
  className: "skippr:sticky skippr:top-0 skippr:z-10 skippr:flex skippr:shrink-0 skippr:items-center skippr:justify-between skippr:border-b skippr:border-border skippr:bg-primary skippr:px-4 skippr:py-3",
1054
1165
  children: [
1055
- /* @__PURE__ */ jsx4("p", {
1166
+ /* @__PURE__ */ jsx5("p", {
1056
1167
  className: "skippr:text-sm skippr:font-semibold skippr:text-primary-foreground",
1057
1168
  children: "Skippr"
1058
1169
  }),
1059
- /* @__PURE__ */ jsxs4("div", {
1170
+ /* @__PURE__ */ jsxs5("div", {
1060
1171
  className: "skippr:flex skippr:items-center skippr:gap-2",
1061
1172
  children: [
1062
- isConnected && /* @__PURE__ */ jsxs4("div", {
1173
+ isConnected && /* @__PURE__ */ jsxs5("div", {
1063
1174
  className: "skippr:flex skippr:items-center skippr:gap-1.5 skippr:rounded-full skippr:bg-primary-foreground/20 skippr:px-2.5 skippr:py-1",
1064
1175
  children: [
1065
- /* @__PURE__ */ jsxs4("span", {
1176
+ /* @__PURE__ */ jsxs5("span", {
1066
1177
  className: "skippr:relative skippr:flex skippr:size-1.5",
1067
1178
  children: [
1068
- /* @__PURE__ */ jsx4("span", {
1179
+ /* @__PURE__ */ jsx5("span", {
1069
1180
  className: "skippr:absolute skippr:inline-flex skippr:h-full skippr:w-full skippr:animate-ping skippr:rounded-full skippr:bg-red-400 skippr:opacity-75"
1070
1181
  }),
1071
- /* @__PURE__ */ jsx4("span", {
1182
+ /* @__PURE__ */ jsx5("span", {
1072
1183
  className: "skippr:relative skippr:inline-flex skippr:size-1.5 skippr:rounded-full skippr:bg-red-400"
1073
1184
  })
1074
1185
  ]
1075
1186
  }),
1076
- /* @__PURE__ */ jsx4("span", {
1187
+ /* @__PURE__ */ jsx5("span", {
1077
1188
  className: "skippr:text-[10px] skippr:font-medium skippr:text-primary-foreground",
1078
1189
  children: "REC"
1079
1190
  }),
1080
- /* @__PURE__ */ jsx4("span", {
1191
+ /* @__PURE__ */ jsx5("span", {
1081
1192
  className: "skippr:text-[10px] skippr:font-mono skippr:text-primary-foreground",
1082
1193
  children: formatTime(elapsed)
1083
1194
  })
1084
1195
  ]
1085
1196
  }),
1086
- minimizable && /* @__PURE__ */ jsx4("button", {
1197
+ minimizable && /* @__PURE__ */ jsx5("button", {
1087
1198
  type: "button",
1088
1199
  onClick: minimizePanel,
1089
1200
  "aria-label": "Minimize",
1090
1201
  className: "skippr:flex skippr:size-6 skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:rounded-md skippr:text-primary-foreground/70 skippr:transition-colors skippr:hover:bg-primary-foreground/10 skippr:hover:text-primary-foreground",
1091
- children: /* @__PURE__ */ jsx4(Minimize2, {
1202
+ children: /* @__PURE__ */ jsx5(Minimize2, {
1092
1203
  className: "skippr:size-3.5"
1093
1204
  })
1094
1205
  })
@@ -1099,26 +1210,26 @@ function ChatHeader() {
1099
1210
  }
1100
1211
 
1101
1212
  // src/components/LoadingDots.tsx
1102
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1213
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1103
1214
  function LoadingDots({ label }) {
1104
- return /* @__PURE__ */ jsxs5("div", {
1215
+ return /* @__PURE__ */ jsxs6("div", {
1105
1216
  className: "skippr:flex skippr:items-center skippr:gap-2 skippr:py-4",
1106
1217
  children: [
1107
- /* @__PURE__ */ jsxs5("div", {
1218
+ /* @__PURE__ */ jsxs6("div", {
1108
1219
  className: "skippr:flex skippr:gap-1",
1109
1220
  children: [
1110
- /* @__PURE__ */ jsx5("span", {
1221
+ /* @__PURE__ */ jsx6("span", {
1111
1222
  className: "skippr:size-1.5 skippr:rounded-full skippr:bg-muted-foreground/40 skippr:animate-bounce skippr:[animation-delay:0ms]"
1112
1223
  }),
1113
- /* @__PURE__ */ jsx5("span", {
1224
+ /* @__PURE__ */ jsx6("span", {
1114
1225
  className: "skippr:size-1.5 skippr:rounded-full skippr:bg-muted-foreground/40 skippr:animate-bounce skippr:[animation-delay:150ms]"
1115
1226
  }),
1116
- /* @__PURE__ */ jsx5("span", {
1227
+ /* @__PURE__ */ jsx6("span", {
1117
1228
  className: "skippr:size-1.5 skippr:rounded-full skippr:bg-muted-foreground/40 skippr:animate-bounce skippr:[animation-delay:300ms]"
1118
1229
  })
1119
1230
  ]
1120
1231
  }),
1121
- /* @__PURE__ */ jsx5("p", {
1232
+ /* @__PURE__ */ jsx6("p", {
1122
1233
  className: "skippr:text-xs skippr:text-muted-foreground",
1123
1234
  children: label
1124
1235
  })
@@ -1131,7 +1242,7 @@ import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef3
1131
1242
 
1132
1243
  // src/components/ui/button.tsx
1133
1244
  import { forwardRef as forwardRef3 } from "react";
1134
- import { jsx as jsx6 } from "react/jsx-runtime";
1245
+ import { jsx as jsx7 } from "react/jsx-runtime";
1135
1246
  var variantClasses = {
1136
1247
  default: "skippr:bg-primary skippr:text-primary-foreground skippr:hover:bg-primary/90",
1137
1248
  destructive: "skippr:bg-destructive skippr:text-white skippr:hover:bg-destructive/90",
@@ -1150,7 +1261,7 @@ var sizeClasses = {
1150
1261
  "icon-lg": "skippr:size-10"
1151
1262
  };
1152
1263
  var Button = forwardRef3(({ className, variant = "default", size = "default", ...props }, ref) => {
1153
- return /* @__PURE__ */ jsx6("button", {
1264
+ return /* @__PURE__ */ jsx7("button", {
1154
1265
  className: cn("skippr:inline-flex skippr:items-center skippr:justify-center skippr:gap-2 skippr:whitespace-nowrap skippr:rounded-md skippr:text-sm skippr:font-medium skippr:ring-offset-background skippr:transition-all skippr:cursor-pointer skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-ring skippr:focus-visible:ring-offset-2 skippr:disabled:pointer-events-none skippr:disabled:opacity-50 skippr:shrink-0 skippr:[&_svg]:pointer-events-none skippr:[&_svg:not([class*='size-'])]:size-4 skippr:[&_svg]:shrink-0", variantClasses[variant], sizeClasses[size], className),
1155
1266
  ref,
1156
1267
  ...props
@@ -1159,7 +1270,7 @@ var Button = forwardRef3(({ className, variant = "default", size = "default", ..
1159
1270
  Button.displayName = "Button";
1160
1271
 
1161
1272
  // src/components/LoginFlow.tsx
1162
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1273
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1163
1274
  var OTP_LENGTH = 6;
1164
1275
  var DIGIT_KEYS = ["d0", "d1", "d2", "d3", "d4", "d5"];
1165
1276
  function LoginFlow({ requestOtp, verifyOtp, error, isSubmitting }) {
@@ -1180,7 +1291,7 @@ function LoginFlow({ requestOtp, verifyOtp, error, isSubmitting }) {
1180
1291
  await requestOtp(email);
1181
1292
  }, [requestOtp, email]);
1182
1293
  if (step === "otp") {
1183
- return /* @__PURE__ */ jsx7(OtpStep, {
1294
+ return /* @__PURE__ */ jsx8(OtpStep, {
1184
1295
  email,
1185
1296
  onSubmit: handleVerifyOtp,
1186
1297
  onResend: handleResend,
@@ -1189,7 +1300,7 @@ function LoginFlow({ requestOtp, verifyOtp, error, isSubmitting }) {
1189
1300
  isSubmitting
1190
1301
  });
1191
1302
  }
1192
- return /* @__PURE__ */ jsx7(EmailStep, {
1303
+ return /* @__PURE__ */ jsx8(EmailStep, {
1193
1304
  email,
1194
1305
  onEmailChange: setEmail,
1195
1306
  onSubmit: handleRequestOtp,
@@ -1203,30 +1314,30 @@ function EmailStep({ email, onEmailChange, onSubmit, error, isSubmitting }) {
1203
1314
  if (email.trim())
1204
1315
  onSubmit(email.trim());
1205
1316
  }
1206
- return /* @__PURE__ */ jsxs6("div", {
1317
+ return /* @__PURE__ */ jsxs7("div", {
1207
1318
  className: "skippr:flex skippr:flex-1 skippr:flex-col skippr:px-4 skippr:py-4",
1208
1319
  children: [
1209
- /* @__PURE__ */ jsxs6("div", {
1320
+ /* @__PURE__ */ jsxs7("div", {
1210
1321
  className: "skippr:mb-4 skippr:text-center",
1211
1322
  children: [
1212
- /* @__PURE__ */ jsx7(Mail, {
1323
+ /* @__PURE__ */ jsx8(Mail, {
1213
1324
  className: "skippr:mx-auto skippr:mb-2 skippr:size-6 skippr:text-primary"
1214
1325
  }),
1215
- /* @__PURE__ */ jsx7("p", {
1326
+ /* @__PURE__ */ jsx8("p", {
1216
1327
  className: "skippr:text-sm skippr:font-medium skippr:text-foreground",
1217
1328
  children: "Sign in to continue"
1218
1329
  }),
1219
- /* @__PURE__ */ jsx7("p", {
1330
+ /* @__PURE__ */ jsx8("p", {
1220
1331
  className: "skippr:mt-1 skippr:text-xs skippr:text-muted-foreground",
1221
1332
  children: "Your email will be used to identify you across sessions"
1222
1333
  })
1223
1334
  ]
1224
1335
  }),
1225
- /* @__PURE__ */ jsxs6("form", {
1336
+ /* @__PURE__ */ jsxs7("form", {
1226
1337
  onSubmit: handleSubmit,
1227
1338
  className: "skippr:flex skippr:flex-col skippr:gap-3",
1228
1339
  children: [
1229
- /* @__PURE__ */ jsx7("input", {
1340
+ /* @__PURE__ */ jsx8("input", {
1230
1341
  type: "email",
1231
1342
  placeholder: "you@example.com",
1232
1343
  value: email,
@@ -1235,15 +1346,15 @@ function EmailStep({ email, onEmailChange, onSubmit, error, isSubmitting }) {
1235
1346
  required: true,
1236
1347
  className: "skippr:w-full skippr:rounded-md skippr:border skippr:border-border skippr:bg-background skippr:px-3 skippr:py-2 skippr:text-sm skippr:text-foreground skippr:placeholder-muted-foreground skippr:outline-none focus:skippr:ring-2 focus:skippr:ring-primary/30 focus:skippr:border-primary disabled:skippr:opacity-50"
1237
1348
  }),
1238
- /* @__PURE__ */ jsx7(Button, {
1349
+ /* @__PURE__ */ jsx8(Button, {
1239
1350
  type: "submit",
1240
1351
  disabled: isSubmitting || !email.trim(),
1241
1352
  className: "skippr:w-full",
1242
- children: isSubmitting ? /* @__PURE__ */ jsx7(LoaderCircle, {
1353
+ children: isSubmitting ? /* @__PURE__ */ jsx8(LoaderCircle, {
1243
1354
  className: "skippr:size-4 skippr:animate-spin"
1244
1355
  }) : "Continue"
1245
1356
  }),
1246
- error && /* @__PURE__ */ jsx7("p", {
1357
+ error && /* @__PURE__ */ jsx8("p", {
1247
1358
  className: "skippr:text-xs skippr:text-center skippr:text-destructive",
1248
1359
  children: error
1249
1360
  })
@@ -1323,22 +1434,22 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
1323
1434
  submittedRef.current = false;
1324
1435
  inputRefs.current[0]?.focus();
1325
1436
  }
1326
- return /* @__PURE__ */ jsxs6("div", {
1437
+ return /* @__PURE__ */ jsxs7("div", {
1327
1438
  className: "skippr:flex skippr:flex-1 skippr:flex-col skippr:px-4 skippr:py-4",
1328
1439
  children: [
1329
- /* @__PURE__ */ jsxs6("div", {
1440
+ /* @__PURE__ */ jsxs7("div", {
1330
1441
  className: "skippr:mb-4 skippr:text-center",
1331
1442
  children: [
1332
- /* @__PURE__ */ jsx7("p", {
1443
+ /* @__PURE__ */ jsx8("p", {
1333
1444
  className: "skippr:text-sm skippr:font-medium skippr:text-foreground",
1334
1445
  children: "Enter verification code"
1335
1446
  }),
1336
- /* @__PURE__ */ jsxs6("p", {
1447
+ /* @__PURE__ */ jsxs7("p", {
1337
1448
  className: "skippr:mt-1 skippr:text-xs skippr:text-muted-foreground",
1338
1449
  children: [
1339
1450
  "We sent a 6-digit code to",
1340
1451
  " ",
1341
- /* @__PURE__ */ jsx7("span", {
1452
+ /* @__PURE__ */ jsx8("span", {
1342
1453
  className: "skippr:font-medium skippr:text-foreground",
1343
1454
  children: email
1344
1455
  })
@@ -1346,13 +1457,13 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
1346
1457
  })
1347
1458
  ]
1348
1459
  }),
1349
- /* @__PURE__ */ jsxs6("form", {
1460
+ /* @__PURE__ */ jsxs7("form", {
1350
1461
  onSubmit: handleSubmit,
1351
1462
  className: "skippr:flex skippr:flex-col skippr:gap-3",
1352
1463
  children: [
1353
- /* @__PURE__ */ jsx7("div", {
1464
+ /* @__PURE__ */ jsx8("div", {
1354
1465
  className: "skippr:flex skippr:justify-center skippr:gap-1.5",
1355
- children: digits.map((digit, index2) => /* @__PURE__ */ jsx7("input", {
1466
+ children: digits.map((digit, index2) => /* @__PURE__ */ jsx8("input", {
1356
1467
  ref: (el) => {
1357
1468
  inputRefs.current[index2] = el;
1358
1469
  },
@@ -1367,29 +1478,29 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
1367
1478
  className: "skippr:h-10 skippr:w-10 skippr:rounded-md skippr:border skippr:border-border skippr:bg-background skippr:text-center skippr:text-sm skippr:font-semibold skippr:text-foreground skippr:outline-none focus:skippr:ring-2 focus:skippr:ring-primary/30 focus:skippr:border-primary disabled:skippr:opacity-50"
1368
1479
  }, DIGIT_KEYS[index2]))
1369
1480
  }),
1370
- error && /* @__PURE__ */ jsx7("p", {
1481
+ error && /* @__PURE__ */ jsx8("p", {
1371
1482
  className: "skippr:text-xs skippr:text-center skippr:text-destructive",
1372
1483
  children: error
1373
1484
  }),
1374
- /* @__PURE__ */ jsx7(Button, {
1485
+ /* @__PURE__ */ jsx8(Button, {
1375
1486
  type: "submit",
1376
1487
  disabled: isSubmitting || digits.join("").length !== OTP_LENGTH,
1377
1488
  className: "skippr:w-full",
1378
- children: isSubmitting ? /* @__PURE__ */ jsx7(LoaderCircle, {
1489
+ children: isSubmitting ? /* @__PURE__ */ jsx8(LoaderCircle, {
1379
1490
  className: "skippr:size-4 skippr:animate-spin"
1380
1491
  }) : "Verify"
1381
1492
  }),
1382
- /* @__PURE__ */ jsxs6("div", {
1493
+ /* @__PURE__ */ jsxs7("div", {
1383
1494
  className: "skippr:flex skippr:items-center skippr:justify-between skippr:text-xs",
1384
1495
  children: [
1385
- /* @__PURE__ */ jsx7("button", {
1496
+ /* @__PURE__ */ jsx8("button", {
1386
1497
  type: "button",
1387
1498
  onClick: onBack,
1388
1499
  disabled: isSubmitting,
1389
1500
  className: "skippr:text-muted-foreground hover:skippr:text-foreground skippr:transition-colors disabled:skippr:opacity-50",
1390
1501
  children: "Change email"
1391
1502
  }),
1392
- /* @__PURE__ */ jsx7("button", {
1503
+ /* @__PURE__ */ jsx8("button", {
1393
1504
  type: "button",
1394
1505
  onClick: handleResend,
1395
1506
  disabled: isSubmitting || resendCooldown > 0,
@@ -1405,50 +1516,50 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
1405
1516
  }
1406
1517
 
1407
1518
  // src/components/MeetingControls.tsx
1408
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1519
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1409
1520
  var CONTROL_BUTTON = "skippr:flex skippr:size-11 skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:rounded-full skippr:transition-colors";
1410
1521
  function MeetingControls({ onHangUp }) {
1411
1522
  const { isMuted, toggleMute, isScreenSharing, toggleScreenShare } = useMediaControls();
1412
- return /* @__PURE__ */ jsxs7("div", {
1523
+ return /* @__PURE__ */ jsxs8("div", {
1413
1524
  className: "skippr:shrink-0 skippr:border-t skippr:border-border skippr:bg-background skippr:px-4 skippr:py-4",
1414
1525
  children: [
1415
- /* @__PURE__ */ jsxs7("div", {
1526
+ /* @__PURE__ */ jsxs8("div", {
1416
1527
  className: "skippr:flex skippr:items-center skippr:justify-center skippr:gap-3",
1417
1528
  children: [
1418
- /* @__PURE__ */ jsx8("button", {
1529
+ /* @__PURE__ */ jsx9("button", {
1419
1530
  type: "button",
1420
1531
  onClick: toggleMute,
1421
1532
  "aria-label": isMuted ? "Unmute" : "Mute",
1422
1533
  className: cn(CONTROL_BUTTON, isMuted ? "skippr:bg-destructive/15 skippr:text-destructive skippr:hover:bg-destructive/25" : "skippr:bg-muted skippr:text-foreground skippr:hover:bg-muted/80"),
1423
- children: isMuted ? /* @__PURE__ */ jsx8(MicOff, {
1534
+ children: isMuted ? /* @__PURE__ */ jsx9(MicOff, {
1424
1535
  className: "skippr:size-5"
1425
- }) : /* @__PURE__ */ jsx8(Mic, {
1536
+ }) : /* @__PURE__ */ jsx9(Mic, {
1426
1537
  className: "skippr:size-5"
1427
1538
  })
1428
1539
  }),
1429
- /* @__PURE__ */ jsx8("button", {
1540
+ /* @__PURE__ */ jsx9("button", {
1430
1541
  type: "button",
1431
1542
  onClick: toggleScreenShare,
1432
1543
  "aria-label": isScreenSharing ? "Stop sharing screen" : "Share screen",
1433
1544
  className: cn(CONTROL_BUTTON, isScreenSharing ? "skippr:bg-bubble skippr:text-white skippr:hover:brightness-110" : "skippr:bg-muted skippr:text-foreground skippr:hover:bg-muted/80"),
1434
- children: isScreenSharing ? /* @__PURE__ */ jsx8(MonitorOff, {
1545
+ children: isScreenSharing ? /* @__PURE__ */ jsx9(MonitorOff, {
1435
1546
  className: "skippr:size-5"
1436
- }) : /* @__PURE__ */ jsx8(Monitor, {
1547
+ }) : /* @__PURE__ */ jsx9(Monitor, {
1437
1548
  className: "skippr:size-5"
1438
1549
  })
1439
1550
  }),
1440
- /* @__PURE__ */ jsx8("button", {
1551
+ /* @__PURE__ */ jsx9("button", {
1441
1552
  type: "button",
1442
1553
  onClick: onHangUp,
1443
1554
  "aria-label": "End session",
1444
1555
  className: cn(CONTROL_BUTTON, "skippr:bg-destructive skippr:text-destructive-foreground skippr:hover:bg-destructive/90"),
1445
- children: /* @__PURE__ */ jsx8(PhoneOff, {
1556
+ children: /* @__PURE__ */ jsx9(PhoneOff, {
1446
1557
  className: "skippr:size-5"
1447
1558
  })
1448
1559
  })
1449
1560
  ]
1450
1561
  }),
1451
- /* @__PURE__ */ jsx8("p", {
1562
+ /* @__PURE__ */ jsx9("p", {
1452
1563
  className: "skippr:mt-3 skippr:text-center skippr:text-[10px] skippr:text-muted-foreground",
1453
1564
  children: "Powered by Skippr"
1454
1565
  })
@@ -1461,7 +1572,7 @@ import { useEffect as useEffect10, useRef as useRef5 } from "react";
1461
1572
 
1462
1573
  // src/components/ChatInput.tsx
1463
1574
  import { useEffect as useEffect9, useRef as useRef4, useState as useState7 } from "react";
1464
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1575
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1465
1576
  var MAX_INPUT_HEIGHT = 60;
1466
1577
  function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
1467
1578
  const [inputText, setInputText] = useState7("");
@@ -1498,13 +1609,13 @@ function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
1498
1609
  handleSubmit(e);
1499
1610
  }
1500
1611
  }
1501
- return /* @__PURE__ */ jsx9("form", {
1612
+ return /* @__PURE__ */ jsx10("form", {
1502
1613
  onSubmit: handleSubmit,
1503
1614
  className: "skippr:border-t skippr:border-border skippr:p-3",
1504
- children: /* @__PURE__ */ jsxs8("div", {
1615
+ children: /* @__PURE__ */ jsxs9("div", {
1505
1616
  className: "skippr:flex skippr:items-center skippr:gap-2 skippr:rounded-xl skippr:bg-background skippr:ring-1 skippr:ring-foreground/10 skippr:px-3 skippr:py-2",
1506
1617
  children: [
1507
- /* @__PURE__ */ jsx9("textarea", {
1618
+ /* @__PURE__ */ jsx10("textarea", {
1508
1619
  ref: textareaRef,
1509
1620
  rows: 1,
1510
1621
  value: inputText,
@@ -1514,12 +1625,12 @@ function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
1514
1625
  className: "skippr:flex-1 skippr:resize-none skippr:overflow-y-auto skippr:bg-transparent skippr:text-sm skippr:leading-5 skippr:text-foreground skippr:placeholder:text-muted-foreground skippr:outline-none",
1515
1626
  style: { maxHeight: `${MAX_INPUT_HEIGHT}px` }
1516
1627
  }),
1517
- /* @__PURE__ */ jsx9("button", {
1628
+ /* @__PURE__ */ jsx10("button", {
1518
1629
  type: "submit",
1519
1630
  disabled: !canSend,
1520
1631
  "aria-label": "Send message",
1521
1632
  className: cn("skippr:flex skippr:size-8 skippr:shrink-0 skippr:items-center skippr:justify-center skippr:rounded-lg skippr:transition-colors", canSend ? "skippr:bg-primary skippr:text-primary-foreground skippr:hover:bg-primary/90" : "skippr:bg-muted-foreground/20 skippr:text-muted-foreground/60"),
1522
- children: /* @__PURE__ */ jsx9(Send, {
1633
+ children: /* @__PURE__ */ jsx10(Send, {
1523
1634
  className: "skippr:size-3.5"
1524
1635
  })
1525
1636
  })
@@ -1529,7 +1640,7 @@ function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
1529
1640
  }
1530
1641
 
1531
1642
  // src/components/ChatMessage.tsx
1532
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1643
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1533
1644
  function formatTimestamp(ts) {
1534
1645
  return new Date(ts).toLocaleTimeString("en-US", {
1535
1646
  hour: "numeric",
@@ -1539,23 +1650,23 @@ function formatTimestamp(ts) {
1539
1650
  }
1540
1651
  function ChatMessage({ message }) {
1541
1652
  const isAgent = message.role === "assistant";
1542
- return /* @__PURE__ */ jsxs9("div", {
1653
+ return /* @__PURE__ */ jsxs10("div", {
1543
1654
  className: cn("skippr:flex skippr:gap-2", isAgent ? "skippr:items-start" : "skippr:justify-end"),
1544
1655
  children: [
1545
- isAgent && /* @__PURE__ */ jsx10("div", {
1656
+ isAgent && /* @__PURE__ */ jsx11("div", {
1546
1657
  className: "skippr:mt-0.5 skippr:flex skippr:size-7 skippr:shrink-0 skippr:items-center skippr:justify-center skippr:rounded-md skippr:bg-primary",
1547
- children: /* @__PURE__ */ jsx10(Sparkles, {
1658
+ children: /* @__PURE__ */ jsx11(Sparkles, {
1548
1659
  className: "skippr:size-3.5 skippr:text-primary-foreground"
1549
1660
  })
1550
1661
  }),
1551
- /* @__PURE__ */ jsxs9("div", {
1662
+ /* @__PURE__ */ jsxs10("div", {
1552
1663
  className: cn("skippr:flex skippr:max-w-[80%] skippr:flex-col", isAgent ? "skippr:items-start" : "skippr:items-end"),
1553
1664
  children: [
1554
- /* @__PURE__ */ jsx10("div", {
1665
+ /* @__PURE__ */ jsx11("div", {
1555
1666
  className: cn("skippr:rounded-2xl skippr:px-4 skippr:py-2.5 skippr:text-sm skippr:leading-relaxed", isAgent ? "skippr:border skippr:border-border skippr:bg-card skippr:text-foreground" : "skippr:bg-primary skippr:text-primary-foreground"),
1556
1667
  children: message.content
1557
1668
  }),
1558
- message.timestamp && /* @__PURE__ */ jsx10("span", {
1669
+ message.timestamp && /* @__PURE__ */ jsx11("span", {
1559
1670
  className: "skippr:mt-1 skippr:px-1 skippr:text-[10px] skippr:text-muted-foreground/60",
1560
1671
  children: formatTimestamp(message.timestamp)
1561
1672
  })
@@ -1566,33 +1677,33 @@ function ChatMessage({ message }) {
1566
1677
  }
1567
1678
 
1568
1679
  // src/components/TypingIndicator.tsx
1569
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1680
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1570
1681
  function TypingIndicator() {
1571
- return /* @__PURE__ */ jsxs10("div", {
1682
+ return /* @__PURE__ */ jsxs11("div", {
1572
1683
  className: "skippr:flex skippr:items-start skippr:gap-2 skippr:animate-skippr-tab-fade",
1573
1684
  children: [
1574
- /* @__PURE__ */ jsx11("div", {
1685
+ /* @__PURE__ */ jsx12("div", {
1575
1686
  className: "skippr:mt-0.5 skippr:flex skippr:size-7 skippr:shrink-0 skippr:items-center skippr:justify-center skippr:rounded-md skippr:bg-primary",
1576
- children: /* @__PURE__ */ jsx11(Sparkles, {
1687
+ children: /* @__PURE__ */ jsx12(Sparkles, {
1577
1688
  className: "skippr:size-3.5 skippr:text-primary-foreground"
1578
1689
  })
1579
1690
  }),
1580
- /* @__PURE__ */ jsxs10("div", {
1691
+ /* @__PURE__ */ jsxs11("div", {
1581
1692
  className: "skippr:inline-flex skippr:items-center skippr:gap-1 skippr:rounded-2xl skippr:border skippr:border-primary/20 skippr:bg-primary/10 skippr:px-4 skippr:py-2 skippr:text-xs skippr:text-primary",
1582
1693
  children: [
1583
- /* @__PURE__ */ jsx11("span", {
1694
+ /* @__PURE__ */ jsx12("span", {
1584
1695
  children: "Agent is analyzing your screen"
1585
1696
  }),
1586
- /* @__PURE__ */ jsxs10("span", {
1697
+ /* @__PURE__ */ jsxs11("span", {
1587
1698
  className: "skippr:inline-flex skippr:items-center skippr:gap-[2px]",
1588
1699
  children: [
1589
- /* @__PURE__ */ jsx11("span", {
1700
+ /* @__PURE__ */ jsx12("span", {
1590
1701
  className: "skippr:size-1 skippr:rounded-full skippr:bg-primary skippr:animate-skippr-thinking-dot skippr:[animation-delay:0ms]"
1591
1702
  }),
1592
- /* @__PURE__ */ jsx11("span", {
1703
+ /* @__PURE__ */ jsx12("span", {
1593
1704
  className: "skippr:size-1 skippr:rounded-full skippr:bg-primary skippr:animate-skippr-thinking-dot skippr:[animation-delay:200ms]"
1594
1705
  }),
1595
- /* @__PURE__ */ jsx11("span", {
1706
+ /* @__PURE__ */ jsx12("span", {
1596
1707
  className: "skippr:size-1 skippr:rounded-full skippr:bg-primary skippr:animate-skippr-thinking-dot skippr:[animation-delay:400ms]"
1597
1708
  })
1598
1709
  ]
@@ -1604,7 +1715,7 @@ function TypingIndicator() {
1604
1715
  }
1605
1716
 
1606
1717
  // src/components/MessageList.tsx
1607
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1718
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1608
1719
  function MessageList({
1609
1720
  messages,
1610
1721
  isStreaming,
@@ -1618,25 +1729,25 @@ function MessageList({
1618
1729
  scrollRef.current?.scrollIntoView({ behavior: "smooth" });
1619
1730
  }, [messages.length, lastMessage?.content]);
1620
1731
  const showTyping = isStreaming && lastMessage?.role === "assistant" && lastMessage.content === "";
1621
- return /* @__PURE__ */ jsxs11("div", {
1732
+ return /* @__PURE__ */ jsxs12("div", {
1622
1733
  className: "skippr:flex skippr:min-h-0 skippr:flex-1 skippr:flex-col",
1623
1734
  children: [
1624
- /* @__PURE__ */ jsxs11("div", {
1735
+ /* @__PURE__ */ jsxs12("div", {
1625
1736
  className: "skippr:min-h-0 skippr:flex-1 skippr:space-y-4 skippr:overflow-y-auto skippr:p-4",
1626
1737
  children: [
1627
- messages.length === 0 && !showTyping && /* @__PURE__ */ jsx12(LoadingDots, {
1738
+ messages.length === 0 && !showTyping && /* @__PURE__ */ jsx13(LoadingDots, {
1628
1739
  label: "Waiting for conversation to begin..."
1629
1740
  }),
1630
- messages.map((message) => /* @__PURE__ */ jsx12(ChatMessage, {
1741
+ messages.map((message) => /* @__PURE__ */ jsx13(ChatMessage, {
1631
1742
  message
1632
1743
  }, message.id)),
1633
- showTyping && /* @__PURE__ */ jsx12(TypingIndicator, {}),
1634
- /* @__PURE__ */ jsx12("div", {
1744
+ showTyping && /* @__PURE__ */ jsx13(TypingIndicator, {}),
1745
+ /* @__PURE__ */ jsx13("div", {
1635
1746
  ref: scrollRef
1636
1747
  })
1637
1748
  ]
1638
1749
  }),
1639
- /* @__PURE__ */ jsx12(ChatInput, {
1750
+ /* @__PURE__ */ jsx13(ChatInput, {
1640
1751
  sendChatMessage,
1641
1752
  isSendingChat,
1642
1753
  autoFocus
@@ -1646,49 +1757,49 @@ function MessageList({
1646
1757
  }
1647
1758
 
1648
1759
  // src/components/SessionAgenda.tsx
1649
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1650
- function SessionAgenda({ phases }) {
1651
- if (phases.length === 0) {
1652
- return /* @__PURE__ */ jsx13("div", {
1760
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1761
+ function SessionAgenda({ phases, hasStarted }) {
1762
+ if (phases.length === 0 || !hasStarted) {
1763
+ return /* @__PURE__ */ jsx14("div", {
1653
1764
  className: "skippr:flex skippr:flex-1 skippr:items-center skippr:justify-center",
1654
- children: /* @__PURE__ */ jsx13(LoadingDots, {
1765
+ children: /* @__PURE__ */ jsx14(LoadingDots, {
1655
1766
  label: "Waiting for agenda to load..."
1656
1767
  })
1657
1768
  });
1658
1769
  }
1659
- return /* @__PURE__ */ jsx13("div", {
1770
+ return /* @__PURE__ */ jsx14("div", {
1660
1771
  className: "skippr:flex-1 skippr:overflow-y-auto skippr:px-4 skippr:py-4",
1661
- children: /* @__PURE__ */ jsx13("div", {
1772
+ children: /* @__PURE__ */ jsx14("div", {
1662
1773
  className: "skippr:space-y-1",
1663
1774
  children: phases.map((phase) => {
1664
1775
  const isActive = phase.status === "active";
1665
1776
  const isCompleted = phase.status === "completed";
1666
- return /* @__PURE__ */ jsxs12("div", {
1777
+ return /* @__PURE__ */ jsxs13("div", {
1667
1778
  className: cn("skippr:flex skippr:items-start skippr:gap-2.5 skippr:rounded-lg skippr:p-2 skippr:transition-colors", isActive && "skippr:bg-primary/10"),
1668
1779
  children: [
1669
- /* @__PURE__ */ jsx13("div", {
1780
+ /* @__PURE__ */ jsx14("div", {
1670
1781
  className: "skippr:mt-0.5",
1671
- children: isCompleted ? /* @__PURE__ */ jsx13(CircleCheck, {
1782
+ children: isCompleted ? /* @__PURE__ */ jsx14(CircleCheck, {
1672
1783
  className: "skippr:size-4 skippr:text-chart-3"
1673
- }) : isActive ? /* @__PURE__ */ jsx13(Circle, {
1784
+ }) : isActive ? /* @__PURE__ */ jsx14(Circle, {
1674
1785
  className: "skippr:size-4 skippr:fill-primary/30 skippr:text-primary"
1675
- }) : /* @__PURE__ */ jsx13(Circle, {
1786
+ }) : /* @__PURE__ */ jsx14(Circle, {
1676
1787
  className: "skippr:size-4 skippr:text-muted-foreground/30"
1677
1788
  })
1678
1789
  }),
1679
- /* @__PURE__ */ jsxs12("div", {
1790
+ /* @__PURE__ */ jsxs13("div", {
1680
1791
  className: "skippr:min-w-0 skippr:flex-1",
1681
1792
  children: [
1682
- /* @__PURE__ */ jsx13("p", {
1793
+ /* @__PURE__ */ jsx14("p", {
1683
1794
  className: cn("skippr:text-sm", isCompleted && "skippr:text-muted-foreground skippr:line-through", isActive && "skippr:font-medium skippr:text-foreground", phase.status === "pending" && "skippr:text-muted-foreground"),
1684
1795
  children: phase.name
1685
1796
  }),
1686
- phase.highlights.length > 0 && /* @__PURE__ */ jsx13("ul", {
1797
+ phase.highlights.length > 0 && /* @__PURE__ */ jsx14("ul", {
1687
1798
  className: "skippr:mt-1 skippr:space-y-0.5",
1688
- children: phase.highlights.map((text) => /* @__PURE__ */ jsxs12("li", {
1799
+ children: phase.highlights.map((text) => /* @__PURE__ */ jsxs13("li", {
1689
1800
  className: cn("skippr:flex skippr:items-center skippr:gap-1.5 skippr:text-[11px] skippr:leading-tight", isCompleted ? "skippr:text-muted-foreground/40 skippr:line-through" : "skippr:text-muted-foreground/70"),
1690
1801
  children: [
1691
- /* @__PURE__ */ jsx13("span", {
1802
+ /* @__PURE__ */ jsx14("span", {
1692
1803
  className: "skippr:size-1 skippr:shrink-0 skippr:rounded-full skippr:bg-current"
1693
1804
  }),
1694
1805
  text
@@ -1705,12 +1816,12 @@ function SessionAgenda({ phases }) {
1705
1816
  }
1706
1817
 
1707
1818
  // src/components/SessionWarningBanner.tsx
1708
- import { jsx as jsx14 } from "react/jsx-runtime";
1819
+ import { jsx as jsx15 } from "react/jsx-runtime";
1709
1820
  var SESSION_WARNING_THRESHOLD_SECS = 60;
1710
1821
  function SessionWarningBanner({ remaining }) {
1711
1822
  if (remaining === null || remaining <= 0 || remaining > SESSION_WARNING_THRESHOLD_SECS)
1712
1823
  return null;
1713
- return /* @__PURE__ */ jsx14("div", {
1824
+ return /* @__PURE__ */ jsx15("div", {
1714
1825
  "data-testid": "session-warning-banner",
1715
1826
  className: "skippr:bg-red-50 skippr:px-4 skippr:py-1.5 skippr:text-center skippr:text-xs skippr:font-medium skippr:text-red-700",
1716
1827
  children: "Session ending soon"
@@ -1718,24 +1829,24 @@ function SessionWarningBanner({ remaining }) {
1718
1829
  }
1719
1830
 
1720
1831
  // src/components/StartSessionPrompt.tsx
1721
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1832
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1722
1833
  function StartSessionPrompt({
1723
1834
  onStartSession,
1724
1835
  isStarting,
1725
1836
  error,
1726
1837
  label = "Talk to Skippr"
1727
1838
  }) {
1728
- return /* @__PURE__ */ jsxs13("div", {
1839
+ return /* @__PURE__ */ jsxs14("div", {
1729
1840
  className: "skippr:flex skippr:flex-1 skippr:flex-col skippr:items-center skippr:justify-center skippr:gap-3 skippr:px-4",
1730
1841
  children: [
1731
- /* @__PURE__ */ jsx15("button", {
1842
+ /* @__PURE__ */ jsx16("button", {
1732
1843
  type: "button",
1733
1844
  onClick: onStartSession,
1734
1845
  disabled: isStarting,
1735
1846
  className: "skippr:cursor-pointer skippr:rounded-xl skippr:bg-primary skippr:px-8 skippr:py-3 skippr:text-sm skippr:font-medium skippr:text-primary-foreground skippr:transition-all skippr:hover:bg-primary/90 skippr:disabled:cursor-not-allowed skippr:disabled:opacity-60",
1736
1847
  children: isStarting ? "Starting..." : label
1737
1848
  }),
1738
- error && /* @__PURE__ */ jsx15("p", {
1849
+ error && /* @__PURE__ */ jsx16("p", {
1739
1850
  className: "skippr:text-xs skippr:text-destructive",
1740
1851
  children: error
1741
1852
  })
@@ -1744,7 +1855,7 @@ function StartSessionPrompt({
1744
1855
  }
1745
1856
 
1746
1857
  // src/components/Sidebar.tsx
1747
- import { jsx as jsx16, jsxs as jsxs14, Fragment as Fragment2 } from "react/jsx-runtime";
1858
+ import { jsx as jsx17, jsxs as jsxs15, Fragment as Fragment3 } from "react/jsx-runtime";
1748
1859
  function Sidebar({
1749
1860
  hideControls = false,
1750
1861
  hideHeader = false,
@@ -1785,22 +1896,22 @@ function Sidebar({
1785
1896
  document.body.style.transition = "";
1786
1897
  };
1787
1898
  }, [isSidebar, isPanelOpen, position]);
1788
- return /* @__PURE__ */ jsxs14("div", {
1899
+ return /* @__PURE__ */ jsxs15("div", {
1789
1900
  className: cn("skippr:fixed skippr:z-[9999]", "skippr:bg-card", "skippr:flex skippr:flex-col", "skippr:overflow-hidden", isFloating && "skippr:border skippr:border-border skippr:bottom-[88px] skippr:h-[calc(100vh-112px)] skippr:rounded-2xl skippr:shadow-[0_8px_30px_rgba(0,0,0,0.16),0_4px_12px_rgba(0,0,0,0.08)]", isFloating && (position === "right" ? "skippr:right-6" : "skippr:left-6"), isFloating && "skippr:transition-[opacity,transform] skippr:duration-300 skippr:ease-in-out", isFloating && (position === "right" ? "skippr:origin-bottom-right" : "skippr:origin-bottom-left"), isFloating && !isPanelOpen && "skippr:scale-0 skippr:opacity-0 skippr:pointer-events-none", isFloating && isPanelOpen && "skippr:scale-100 skippr:opacity-100", isSidebar && "skippr:top-0 skippr:h-full", isSidebar && "skippr:transition-[width] skippr:duration-300 skippr:ease-in-out", isSidebar && position === "right" && "skippr:right-0 skippr:border-l skippr:border-l-border", isSidebar && position === "left" && "skippr:left-0 skippr:border-r skippr:border-r-border", isSidebar && !isPanelOpen && "skippr:w-0 skippr:border-0"),
1790
1901
  style: { width: isPanelOpen ? SIDEBAR_WIDTH : undefined },
1791
1902
  children: [
1792
- !hideHeader && /* @__PURE__ */ jsx16(ChatHeader, {}),
1793
- !isAuthenticated && isValidating ? /* @__PURE__ */ jsx16("div", {
1903
+ !hideHeader && /* @__PURE__ */ jsx17(ChatHeader, {}),
1904
+ !isAuthenticated && isValidating ? /* @__PURE__ */ jsx17("div", {
1794
1905
  className: "skippr:flex skippr:flex-1 skippr:items-center skippr:justify-center",
1795
- children: /* @__PURE__ */ jsx16(LoadingDots, {
1906
+ children: /* @__PURE__ */ jsx17(LoadingDots, {
1796
1907
  label: "Loading..."
1797
1908
  })
1798
- }) : !isAuthenticated ? /* @__PURE__ */ jsx16(LoginFlow, {
1909
+ }) : !isAuthenticated ? /* @__PURE__ */ jsx17(LoginFlow, {
1799
1910
  requestOtp,
1800
1911
  verifyOtp,
1801
1912
  error: authError,
1802
1913
  isSubmitting: isAuthSubmitting
1803
- }) : /* @__PURE__ */ jsx16(AuthenticatedContent, {
1914
+ }) : /* @__PURE__ */ jsx17(AuthenticatedContent, {
1804
1915
  isConnected,
1805
1916
  onStartSession: startSession,
1806
1917
  onDisconnect: disconnect,
@@ -1827,50 +1938,50 @@ function AuthenticatedContent({
1827
1938
  startSessionLabel,
1828
1939
  autoFocusChat
1829
1940
  }) {
1830
- return /* @__PURE__ */ jsxs14(Fragment2, {
1941
+ return /* @__PURE__ */ jsxs15(Fragment3, {
1831
1942
  children: [
1832
- isConnected && /* @__PURE__ */ jsx16(ConnectedBanner, {}),
1833
- /* @__PURE__ */ jsxs14("div", {
1943
+ isConnected && /* @__PURE__ */ jsx17(ConnectedBanner, {}),
1944
+ /* @__PURE__ */ jsxs15("div", {
1834
1945
  className: "skippr:flex skippr:gap-2 skippr:border-b skippr:border-border skippr:px-3 skippr:py-2",
1835
1946
  children: [
1836
- /* @__PURE__ */ jsxs14("button", {
1947
+ /* @__PURE__ */ jsxs15("button", {
1837
1948
  type: "button",
1838
1949
  className: cn("skippr:relative skippr:inline-flex skippr:cursor-pointer skippr:items-center skippr:gap-1.5 skippr:rounded-lg skippr:px-3 skippr:py-2 skippr:text-sm skippr:font-medium skippr:transition-all", activeTab === "chat" ? "skippr:text-foreground" : "skippr:text-muted-foreground skippr:hover:text-foreground"),
1839
1950
  onClick: () => onTabChange("chat"),
1840
1951
  children: [
1841
- /* @__PURE__ */ jsx16(MessageCircle, {
1952
+ /* @__PURE__ */ jsx17(MessageCircle, {
1842
1953
  className: "skippr:size-3.5"
1843
1954
  }),
1844
1955
  "Chat",
1845
- activeTab === "chat" && /* @__PURE__ */ jsx16("span", {
1956
+ activeTab === "chat" && /* @__PURE__ */ jsx17("span", {
1846
1957
  className: "skippr:absolute skippr:-bottom-2 skippr:left-3 skippr:right-3 skippr:h-0.5 skippr:rounded-full skippr:bg-foreground"
1847
1958
  })
1848
1959
  ]
1849
1960
  }),
1850
- /* @__PURE__ */ jsxs14("button", {
1961
+ /* @__PURE__ */ jsxs15("button", {
1851
1962
  type: "button",
1852
1963
  className: cn("skippr:relative skippr:inline-flex skippr:cursor-pointer skippr:items-center skippr:gap-1.5 skippr:rounded-lg skippr:px-3 skippr:py-2 skippr:text-sm skippr:font-medium skippr:transition-all", activeTab === "agenda" ? "skippr:text-foreground" : "skippr:text-muted-foreground skippr:hover:text-foreground"),
1853
1964
  onClick: () => onTabChange("agenda"),
1854
1965
  children: [
1855
- /* @__PURE__ */ jsx16(Calendar, {
1966
+ /* @__PURE__ */ jsx17(Calendar, {
1856
1967
  className: "skippr:size-3.5"
1857
1968
  }),
1858
1969
  "Agenda",
1859
- activeTab === "agenda" && /* @__PURE__ */ jsx16("span", {
1970
+ activeTab === "agenda" && /* @__PURE__ */ jsx17("span", {
1860
1971
  className: "skippr:absolute skippr:-bottom-2 skippr:left-3 skippr:right-3 skippr:h-0.5 skippr:rounded-full skippr:bg-foreground"
1861
1972
  })
1862
1973
  ]
1863
1974
  })
1864
1975
  ]
1865
1976
  }),
1866
- /* @__PURE__ */ jsx16("div", {
1977
+ /* @__PURE__ */ jsx17("div", {
1867
1978
  className: "skippr:flex skippr:min-h-0 skippr:flex-1 skippr:flex-col",
1868
- children: isConnected ? /* @__PURE__ */ jsx16(ConnectedBody, {
1979
+ children: isConnected || isStarting ? /* @__PURE__ */ jsx17(ConnectedBody, {
1869
1980
  activeTab,
1870
1981
  autoFocusChat
1871
- }) : /* @__PURE__ */ jsx16("div", {
1982
+ }) : /* @__PURE__ */ jsx17("div", {
1872
1983
  className: "skippr:flex skippr:min-h-0 skippr:flex-1 skippr:flex-col skippr:animate-skippr-tab-fade",
1873
- children: /* @__PURE__ */ jsx16(StartSessionPrompt, {
1984
+ children: /* @__PURE__ */ jsx17(StartSessionPrompt, {
1874
1985
  onStartSession,
1875
1986
  isStarting,
1876
1987
  error,
@@ -1878,7 +1989,7 @@ function AuthenticatedContent({
1878
1989
  })
1879
1990
  }, `${activeTab}-empty`)
1880
1991
  }),
1881
- isConnected && !hideControls && /* @__PURE__ */ jsx16(MeetingControls, {
1992
+ isConnected && !hideControls && /* @__PURE__ */ jsx17(MeetingControls, {
1882
1993
  onHangUp: onDisconnect
1883
1994
  })
1884
1995
  ]
@@ -1886,7 +1997,7 @@ function AuthenticatedContent({
1886
1997
  }
1887
1998
  function ConnectedBanner() {
1888
1999
  const remaining = useSessionRemaining();
1889
- return /* @__PURE__ */ jsx16(SessionWarningBanner, {
2000
+ return /* @__PURE__ */ jsx17(SessionWarningBanner, {
1890
2001
  remaining
1891
2002
  });
1892
2003
  }
@@ -1897,16 +2008,17 @@ function ConnectedBody({
1897
2008
  const { allMessages, agentState, sendChatMessage, isSendingChat } = useCombinedMessages();
1898
2009
  const { phases } = usePhaseUpdates();
1899
2010
  if (activeTab === "agenda") {
1900
- return /* @__PURE__ */ jsx16("div", {
2011
+ return /* @__PURE__ */ jsx17("div", {
1901
2012
  className: "skippr:min-h-0 skippr:flex-1 skippr:overflow-y-auto skippr:animate-skippr-tab-fade",
1902
- children: /* @__PURE__ */ jsx16(SessionAgenda, {
1903
- phases
2013
+ children: /* @__PURE__ */ jsx17(SessionAgenda, {
2014
+ phases,
2015
+ hasStarted: allMessages.length > 0 || agentState === "speaking"
1904
2016
  })
1905
2017
  }, "agenda");
1906
2018
  }
1907
- return /* @__PURE__ */ jsx16("div", {
2019
+ return /* @__PURE__ */ jsx17("div", {
1908
2020
  className: "skippr:flex skippr:min-h-0 skippr:flex-1 skippr:flex-col skippr:animate-skippr-tab-fade",
1909
- children: /* @__PURE__ */ jsx16(MessageList, {
2021
+ children: /* @__PURE__ */ jsx17(MessageList, {
1910
2022
  messages: allMessages,
1911
2023
  isStreaming: agentState === "speaking",
1912
2024
  sendChatMessage,
@@ -1917,30 +2029,28 @@ function ConnectedBody({
1917
2029
  }
1918
2030
 
1919
2031
  // src/components/SidebarTrigger.tsx
1920
- import { jsx as jsx17 } from "react/jsx-runtime";
2032
+ import { jsx as jsx18 } from "react/jsx-runtime";
1921
2033
  function SidebarTrigger() {
1922
2034
  const { isPanelOpen, togglePanel, minimizePanel, minimizable, position, isMinimized } = useLiveAgent();
1923
2035
  if (isMinimized)
1924
2036
  return null;
1925
2037
  const handleClick = isPanelOpen && minimizable ? minimizePanel : togglePanel;
1926
- return /* @__PURE__ */ jsx17("button", {
2038
+ return /* @__PURE__ */ jsx18("button", {
1927
2039
  type: "button",
1928
2040
  onClick: handleClick,
1929
2041
  title: isPanelOpen ? "Close chat" : "Open chat",
1930
2042
  "aria-label": isPanelOpen ? "Close chat" : "Open chat",
1931
2043
  className: cn("skippr:fixed skippr:bottom-6 skippr:z-[9998]", "skippr:flex skippr:size-12 skippr:items-center skippr:justify-center", "skippr:rounded-[14px] skippr:bg-bubble skippr:text-white", "skippr:shadow-[0_4px_16px_rgba(45,43,61,0.45),0_2px_4px_rgba(0,0,0,0.1)] skippr:transition-all", "skippr:cursor-pointer skippr:hover:brightness-110 skippr:hover:-translate-y-0.5 skippr:active:translate-y-0", position === "right" ? "skippr:right-6" : "skippr:left-6"),
1932
- children: isPanelOpen ? /* @__PURE__ */ jsx17(ChevronDown, {
2044
+ children: isPanelOpen ? /* @__PURE__ */ jsx18(ChevronDown, {
1933
2045
  className: "skippr:size-5"
1934
- }) : /* @__PURE__ */ jsx17("img", {
1935
- src: LOGO_URL,
1936
- alt: "Skippr",
2046
+ }) : /* @__PURE__ */ jsx18(Logo, {
1937
2047
  className: "skippr:size-7"
1938
2048
  })
1939
2049
  });
1940
2050
  }
1941
2051
 
1942
2052
  // src/components/LiveAgent.tsx
1943
- import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
2053
+ import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
1944
2054
  function LiveAgent({
1945
2055
  agentId,
1946
2056
  authToken: authTokenProp,
@@ -1955,7 +2065,7 @@ function LiveAgent({
1955
2065
  hideHeader = false,
1956
2066
  startSessionLabel = "Talk to Skippr",
1957
2067
  autoFocusChat = true,
1958
- showObservingBanner = true,
2068
+ showAgentStateBanner = true,
1959
2069
  children
1960
2070
  }) {
1961
2071
  const auth = useAuth({ appKey });
@@ -2078,27 +2188,27 @@ function LiveAgent({
2078
2188
  sidebarTab,
2079
2189
  autoFocusChat
2080
2190
  ]);
2081
- return /* @__PURE__ */ jsx18(LiveAgentContext.Provider, {
2191
+ return /* @__PURE__ */ jsx19(LiveAgentContext.Provider, {
2082
2192
  value: ctx,
2083
- children: /* @__PURE__ */ jsxs15(LiveKitRoom, {
2193
+ children: /* @__PURE__ */ jsxs16(LiveKitRoom, {
2084
2194
  serverUrl: connection?.livekitUrl,
2085
2195
  token: connection?.token,
2086
2196
  connect: shouldConnect,
2087
2197
  audio: true,
2088
2198
  onDisconnected: disconnect,
2089
2199
  children: [
2090
- connection && /* @__PURE__ */ jsx18(RoomAudioRenderer, {}),
2091
- showObservingBanner && /* @__PURE__ */ jsx18(ObservingBanner, {}),
2092
- connection && /* @__PURE__ */ jsx18(AutoStartMedia, {
2200
+ connection && /* @__PURE__ */ jsx19(RoomAudioRenderer, {}),
2201
+ showAgentStateBanner && /* @__PURE__ */ jsx19(AgentStateBanner, {}),
2202
+ connection && /* @__PURE__ */ jsx19(AutoStartMedia, {
2093
2203
  pendingScreenStream
2094
2204
  }),
2095
- isMinimized && /* @__PURE__ */ jsx18(MinimizedBubble, {
2205
+ isMinimized && /* @__PURE__ */ jsx19(MinimizedBubble, {
2096
2206
  welcomeMessage,
2097
2207
  welcomeDismissed,
2098
2208
  onDismissWelcome: dismissWelcome
2099
2209
  }),
2100
- /* @__PURE__ */ jsx18(SidebarTrigger, {}),
2101
- /* @__PURE__ */ jsx18(Sidebar, {
2210
+ /* @__PURE__ */ jsx19(SidebarTrigger, {}),
2211
+ /* @__PURE__ */ jsx19(Sidebar, {
2102
2212
  hideControls,
2103
2213
  hideHeader,
2104
2214
  startSessionLabel