@skippr/live-agent-sdk 0.75.0 → 0.77.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.
package/dist/esm/lib-exports.js
CHANGED
|
@@ -8,7 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
8
8
|
|
|
9
9
|
// src/components/LiveAgent.tsx
|
|
10
10
|
import { LiveKitRoom, RoomAudioRenderer } from "@livekit/components-react";
|
|
11
|
-
import { useCallback as useCallback15, useEffect as
|
|
11
|
+
import { useCallback as useCallback15, useEffect as useEffect27, useMemo as useMemo7, useRef as useRef18, useState as useState19 } from "react";
|
|
12
12
|
|
|
13
13
|
// src/capture/useAgentCursor.ts
|
|
14
14
|
import { useEffect, useState } from "react";
|
|
@@ -481,8 +481,127 @@ function useAuth({ appKey }) {
|
|
|
481
481
|
};
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
+
// src/hooks/useAutoStart.ts
|
|
485
|
+
import { useEffect as useEffect5, useMemo as useMemo2, useRef } from "react";
|
|
486
|
+
|
|
487
|
+
// src/lib/agentMode.ts
|
|
488
|
+
var AGENT_MODE = {
|
|
489
|
+
Standard: "standard",
|
|
490
|
+
AlwaysOn: "always_on"
|
|
491
|
+
};
|
|
492
|
+
var AGENT_MODES = Object.values(AGENT_MODE);
|
|
493
|
+
|
|
494
|
+
// src/lib/sessionStatus.ts
|
|
495
|
+
var SESSION_STATUS = {
|
|
496
|
+
pending: "pending",
|
|
497
|
+
active: "active",
|
|
498
|
+
paused: "paused",
|
|
499
|
+
completed: "completed",
|
|
500
|
+
expired: "expired"
|
|
501
|
+
};
|
|
502
|
+
var SESSION_STATUSES = Object.values(SESSION_STATUS);
|
|
503
|
+
|
|
504
|
+
// src/lib/session.ts
|
|
505
|
+
function mapApiMessages(messages) {
|
|
506
|
+
return messages.filter((message) => message.role !== "system").map((message) => ({
|
|
507
|
+
id: message.id,
|
|
508
|
+
role: message.role === "user" ? "user" : "assistant",
|
|
509
|
+
content: message.content,
|
|
510
|
+
source: "chat",
|
|
511
|
+
timestamp: new Date(message.createdAt).getTime()
|
|
512
|
+
}));
|
|
513
|
+
}
|
|
514
|
+
function getResumableSessionId(currentSession, mode) {
|
|
515
|
+
if (!currentSession)
|
|
516
|
+
return;
|
|
517
|
+
const { id, status } = currentSession;
|
|
518
|
+
if (status === SESSION_STATUS.paused || status === SESSION_STATUS.active)
|
|
519
|
+
return id;
|
|
520
|
+
if (mode === AGENT_MODE.AlwaysOn && (status === SESSION_STATUS.expired || status === SESSION_STATUS.completed))
|
|
521
|
+
return id;
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
function canResumeSession(currentSession, mode) {
|
|
525
|
+
return getResumableSessionId(currentSession, mode) !== undefined;
|
|
526
|
+
}
|
|
527
|
+
function getResumableSession(module) {
|
|
528
|
+
if (!module)
|
|
529
|
+
return null;
|
|
530
|
+
const id = getResumableSessionId(module.currentSession, module.mode);
|
|
531
|
+
return id ? { id, agentId: module.id } : null;
|
|
532
|
+
}
|
|
533
|
+
function getModuleSessionState(currentSession, mode) {
|
|
534
|
+
if (!currentSession)
|
|
535
|
+
return null;
|
|
536
|
+
if (canResumeSession(currentSession, mode))
|
|
537
|
+
return "resume";
|
|
538
|
+
if (mode === AGENT_MODE.Standard) {
|
|
539
|
+
const { status } = currentSession;
|
|
540
|
+
if (status === SESSION_STATUS.completed)
|
|
541
|
+
return "completed";
|
|
542
|
+
if (status === SESSION_STATUS.expired)
|
|
543
|
+
return "expired";
|
|
544
|
+
}
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// src/hooks/useAutoStart.ts
|
|
549
|
+
async function isMicGranted() {
|
|
550
|
+
try {
|
|
551
|
+
if (!navigator.permissions?.query)
|
|
552
|
+
return false;
|
|
553
|
+
const status = await navigator.permissions.query({ name: "microphone" });
|
|
554
|
+
return status.state === "granted";
|
|
555
|
+
} catch {
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
function useAutoStart({
|
|
560
|
+
availableModules,
|
|
561
|
+
isSessionLive,
|
|
562
|
+
bearerToken,
|
|
563
|
+
selectModule
|
|
564
|
+
}) {
|
|
565
|
+
const hasAutoStartedRef = useRef(false);
|
|
566
|
+
const autoStartModule = useMemo2(() => availableModules.find((m) => {
|
|
567
|
+
if (!m.uiPreferences?.autoStart)
|
|
568
|
+
return false;
|
|
569
|
+
const state = getModuleSessionState(m.currentSession, m.mode);
|
|
570
|
+
return state !== "completed" && state !== "expired";
|
|
571
|
+
}) ?? null, [availableModules]);
|
|
572
|
+
useEffect5(() => {
|
|
573
|
+
if (!autoStartModule || hasAutoStartedRef.current)
|
|
574
|
+
return;
|
|
575
|
+
if (isSessionLive || !bearerToken)
|
|
576
|
+
return;
|
|
577
|
+
let cancelled = false;
|
|
578
|
+
const stopWaitingForGesture = () => {
|
|
579
|
+
document.removeEventListener("pointerdown", onFirstGesture, true);
|
|
580
|
+
document.removeEventListener("keydown", onFirstGesture, true);
|
|
581
|
+
};
|
|
582
|
+
const startOnce = () => {
|
|
583
|
+
if (cancelled || hasAutoStartedRef.current)
|
|
584
|
+
return;
|
|
585
|
+
hasAutoStartedRef.current = true;
|
|
586
|
+
stopWaitingForGesture();
|
|
587
|
+
selectModule(autoStartModule.id, { autoStarted: true });
|
|
588
|
+
};
|
|
589
|
+
const onFirstGesture = () => startOnce();
|
|
590
|
+
document.addEventListener("pointerdown", onFirstGesture, true);
|
|
591
|
+
document.addEventListener("keydown", onFirstGesture, true);
|
|
592
|
+
isMicGranted().then((granted) => {
|
|
593
|
+
if (granted)
|
|
594
|
+
startOnce();
|
|
595
|
+
});
|
|
596
|
+
return () => {
|
|
597
|
+
cancelled = true;
|
|
598
|
+
stopWaitingForGesture();
|
|
599
|
+
};
|
|
600
|
+
}, [autoStartModule, isSessionLive, bearerToken, selectModule]);
|
|
601
|
+
}
|
|
602
|
+
|
|
484
603
|
// src/hooks/useAvailableModules.ts
|
|
485
|
-
import { useCallback as useCallback4, useEffect as
|
|
604
|
+
import { useCallback as useCallback4, useEffect as useEffect6, useState as useState5 } from "react";
|
|
486
605
|
var EMPTY_DEFAULT = { agentId: null, sessionId: null };
|
|
487
606
|
var API_URL3 = "https://specialist.skippr.ai/api";
|
|
488
607
|
function useAvailableModules({
|
|
@@ -517,7 +636,7 @@ function useAvailableModules({
|
|
|
517
636
|
setHasResolved(true);
|
|
518
637
|
}
|
|
519
638
|
}, [authedFetch, agentId]);
|
|
520
|
-
|
|
639
|
+
useEffect6(() => {
|
|
521
640
|
if (!enabled || !bearerToken)
|
|
522
641
|
return;
|
|
523
642
|
fetchModules();
|
|
@@ -537,11 +656,11 @@ import { useCallback as useCallback5 } from "react";
|
|
|
537
656
|
|
|
538
657
|
// src/hooks/useAgentState.ts
|
|
539
658
|
import { useRemoteParticipants } from "@livekit/components-react/hooks";
|
|
540
|
-
import { useEffect as
|
|
659
|
+
import { useEffect as useEffect7, useState as useState6 } from "react";
|
|
541
660
|
function useAgentState(attributeKey, parse, initial) {
|
|
542
661
|
const [value, setValue] = useState6(initial);
|
|
543
662
|
const remoteParticipants = useRemoteParticipants();
|
|
544
|
-
|
|
663
|
+
useEffect7(() => {
|
|
545
664
|
const agentParticipant = remoteParticipants.find((p) => p.attributes?.[attributeKey]);
|
|
546
665
|
if (agentParticipant) {
|
|
547
666
|
const attr = agentParticipant.attributes?.[attributeKey];
|
|
@@ -592,70 +711,7 @@ function usePlanUpdates() {
|
|
|
592
711
|
}
|
|
593
712
|
|
|
594
713
|
// src/hooks/useSession.ts
|
|
595
|
-
import { useCallback as useCallback6, useEffect as
|
|
596
|
-
|
|
597
|
-
// src/lib/agentMode.ts
|
|
598
|
-
var AGENT_MODE = {
|
|
599
|
-
Standard: "standard",
|
|
600
|
-
AlwaysOn: "always_on"
|
|
601
|
-
};
|
|
602
|
-
var AGENT_MODES = Object.values(AGENT_MODE);
|
|
603
|
-
|
|
604
|
-
// src/lib/sessionStatus.ts
|
|
605
|
-
var SESSION_STATUS = {
|
|
606
|
-
pending: "pending",
|
|
607
|
-
active: "active",
|
|
608
|
-
paused: "paused",
|
|
609
|
-
completed: "completed",
|
|
610
|
-
expired: "expired"
|
|
611
|
-
};
|
|
612
|
-
var SESSION_STATUSES = Object.values(SESSION_STATUS);
|
|
613
|
-
|
|
614
|
-
// src/lib/session.ts
|
|
615
|
-
function mapApiMessages(messages) {
|
|
616
|
-
return messages.filter((message) => message.role !== "system").map((message) => ({
|
|
617
|
-
id: message.id,
|
|
618
|
-
role: message.role === "user" ? "user" : "assistant",
|
|
619
|
-
content: message.content,
|
|
620
|
-
source: "chat",
|
|
621
|
-
timestamp: new Date(message.createdAt).getTime()
|
|
622
|
-
}));
|
|
623
|
-
}
|
|
624
|
-
function getResumableSessionId(currentSession, mode) {
|
|
625
|
-
if (!currentSession)
|
|
626
|
-
return;
|
|
627
|
-
const { id, status } = currentSession;
|
|
628
|
-
if (status === SESSION_STATUS.paused || status === SESSION_STATUS.active)
|
|
629
|
-
return id;
|
|
630
|
-
if (mode === AGENT_MODE.AlwaysOn && (status === SESSION_STATUS.expired || status === SESSION_STATUS.completed))
|
|
631
|
-
return id;
|
|
632
|
-
return;
|
|
633
|
-
}
|
|
634
|
-
function canResumeSession(currentSession, mode) {
|
|
635
|
-
return getResumableSessionId(currentSession, mode) !== undefined;
|
|
636
|
-
}
|
|
637
|
-
function getResumableSession(module) {
|
|
638
|
-
if (!module)
|
|
639
|
-
return null;
|
|
640
|
-
const id = getResumableSessionId(module.currentSession, module.mode);
|
|
641
|
-
return id ? { id, agentId: module.id } : null;
|
|
642
|
-
}
|
|
643
|
-
function getModuleSessionState(currentSession, mode) {
|
|
644
|
-
if (!currentSession)
|
|
645
|
-
return null;
|
|
646
|
-
if (canResumeSession(currentSession, mode))
|
|
647
|
-
return "resume";
|
|
648
|
-
if (mode === AGENT_MODE.Standard) {
|
|
649
|
-
const { status } = currentSession;
|
|
650
|
-
if (status === SESSION_STATUS.completed)
|
|
651
|
-
return "completed";
|
|
652
|
-
if (status === SESSION_STATUS.expired)
|
|
653
|
-
return "expired";
|
|
654
|
-
}
|
|
655
|
-
return null;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
// src/hooks/useSession.ts
|
|
714
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useRef as useRef2, useState as useState7 } from "react";
|
|
659
715
|
var API_URL4 = "https://specialist.skippr.ai/api";
|
|
660
716
|
async function fetchSessionMessages(sessionId, authedFetch) {
|
|
661
717
|
try {
|
|
@@ -721,11 +777,11 @@ function useSession({
|
|
|
721
777
|
const [pauseTimeoutSeconds, setPauseTimeoutSeconds] = useState7(null);
|
|
722
778
|
const [historyMessages, setHistoryMessages] = useState7([]);
|
|
723
779
|
const [authFailed, setAuthFailed] = useState7(false);
|
|
724
|
-
const tokenRef =
|
|
725
|
-
const getUserTokenRef =
|
|
780
|
+
const tokenRef = useRef2(authToken ? { token: authToken, expiresAt: null } : null);
|
|
781
|
+
const getUserTokenRef = useRef2(getUserToken);
|
|
726
782
|
getUserTokenRef.current = getUserToken ?? (userToken ? () => Promise.resolve(userToken) : undefined);
|
|
727
|
-
const failedBearerRef =
|
|
728
|
-
const inFlightExchangeRef =
|
|
783
|
+
const failedBearerRef = useRef2(null);
|
|
784
|
+
const inFlightExchangeRef = useRef2(null);
|
|
729
785
|
const canExchange = useCallback6(() => !!appKey && !!getUserTokenRef.current, [appKey]);
|
|
730
786
|
const reExchange = useCallback6(async () => {
|
|
731
787
|
if (inFlightExchangeRef.current)
|
|
@@ -801,7 +857,7 @@ function useSession({
|
|
|
801
857
|
setAuthFailed(false);
|
|
802
858
|
return resp;
|
|
803
859
|
}, [canExchange, getValidBearer, reExchange]);
|
|
804
|
-
|
|
860
|
+
useEffect8(() => {
|
|
805
861
|
let stale = false;
|
|
806
862
|
if (authToken) {
|
|
807
863
|
tokenRef.current = { token: authToken, expiresAt: null };
|
|
@@ -820,9 +876,10 @@ function useSession({
|
|
|
820
876
|
stale = true;
|
|
821
877
|
};
|
|
822
878
|
}, [authToken, canExchange, reExchange]);
|
|
823
|
-
const
|
|
879
|
+
const isStartingRef = useRef2(false);
|
|
880
|
+
const pauseOnUnloadRef = useRef2(null);
|
|
824
881
|
pauseOnUnloadRef.current = connection !== null && !isPaused && sessionId && bearerToken ? { sessionId, bearerToken } : null;
|
|
825
|
-
|
|
882
|
+
useEffect8(() => {
|
|
826
883
|
const onPageHide = () => {
|
|
827
884
|
const pending = pauseOnUnloadRef.current;
|
|
828
885
|
if (!pending)
|
|
@@ -837,7 +894,15 @@ function useSession({
|
|
|
837
894
|
window.addEventListener("pagehide", onPageHide);
|
|
838
895
|
return () => window.removeEventListener("pagehide", onPageHide);
|
|
839
896
|
}, []);
|
|
840
|
-
const startSession = useCallback6(async ({
|
|
897
|
+
const startSession = useCallback6(async ({
|
|
898
|
+
agentId,
|
|
899
|
+
agentControls,
|
|
900
|
+
existingSessionId,
|
|
901
|
+
adoptionGoalId,
|
|
902
|
+
autoStarted
|
|
903
|
+
}) => {
|
|
904
|
+
if (isStartingRef.current)
|
|
905
|
+
return;
|
|
841
906
|
if (!bearerToken) {
|
|
842
907
|
setError("No auth token available");
|
|
843
908
|
return;
|
|
@@ -846,6 +911,7 @@ function useSession({
|
|
|
846
911
|
setError("No agent selected");
|
|
847
912
|
return;
|
|
848
913
|
}
|
|
914
|
+
isStartingRef.current = true;
|
|
849
915
|
setIsStarting(true);
|
|
850
916
|
setError("");
|
|
851
917
|
setErrorCode(null);
|
|
@@ -886,7 +952,8 @@ function useSession({
|
|
|
886
952
|
body: JSON.stringify({
|
|
887
953
|
captureMode,
|
|
888
954
|
agentControls: requestAgentControls,
|
|
889
|
-
adoptionGoalId
|
|
955
|
+
adoptionGoalId,
|
|
956
|
+
autoStarted
|
|
890
957
|
})
|
|
891
958
|
});
|
|
892
959
|
if (!startResp.ok) {
|
|
@@ -915,6 +982,7 @@ function useSession({
|
|
|
915
982
|
setError(e instanceof Error ? e.message : "Failed to start session");
|
|
916
983
|
onStartError?.();
|
|
917
984
|
} finally {
|
|
985
|
+
isStartingRef.current = false;
|
|
918
986
|
setIsStarting(false);
|
|
919
987
|
}
|
|
920
988
|
}, [captureMode, bearerToken, authedFetch, onStart, onStartError]);
|
|
@@ -989,7 +1057,7 @@ function useSession({
|
|
|
989
1057
|
}
|
|
990
1058
|
|
|
991
1059
|
// src/hooks/useSessionHistory.ts
|
|
992
|
-
import { useEffect as
|
|
1060
|
+
import { useEffect as useEffect9, useState as useState8 } from "react";
|
|
993
1061
|
var API_URL5 = "https://specialist.skippr.ai/api";
|
|
994
1062
|
var EMPTY = { messages: [], phases: [] };
|
|
995
1063
|
function useSessionHistory({
|
|
@@ -1001,7 +1069,7 @@ function useSessionHistory({
|
|
|
1001
1069
|
const [loadedAgentId, setLoadedAgentId] = useState8(null);
|
|
1002
1070
|
const activeAgentId = enabled && agentId ? agentId : null;
|
|
1003
1071
|
const isLoading = activeAgentId !== null && activeAgentId !== loadedAgentId;
|
|
1004
|
-
|
|
1072
|
+
useEffect9(() => {
|
|
1005
1073
|
if (!enabled || !agentId) {
|
|
1006
1074
|
setHistory(EMPTY);
|
|
1007
1075
|
setLoadedAgentId(null);
|
|
@@ -1114,7 +1182,7 @@ var hasA11yProp = (props) => {
|
|
|
1114
1182
|
};
|
|
1115
1183
|
|
|
1116
1184
|
// ../../node_modules/.bun/lucide-react@1.8.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/context.js
|
|
1117
|
-
import { createContext as createContext3, useContext as useContext3, useMemo as
|
|
1185
|
+
import { createContext as createContext3, useContext as useContext3, useMemo as useMemo3, createElement } from "react";
|
|
1118
1186
|
var LucideContext = createContext3({});
|
|
1119
1187
|
var useLucideContext = () => useContext3(LucideContext);
|
|
1120
1188
|
|
|
@@ -1340,7 +1408,7 @@ var __iconNode23 = [
|
|
|
1340
1408
|
];
|
|
1341
1409
|
var X = createLucideIcon("x", __iconNode23);
|
|
1342
1410
|
// src/components/AgentCursor.tsx
|
|
1343
|
-
import { useContext as useContext4, useEffect as
|
|
1411
|
+
import { useContext as useContext4, useEffect as useEffect10, useLayoutEffect, useRef as useRef3, useState as useState9 } from "react";
|
|
1344
1412
|
|
|
1345
1413
|
// src/capture/elementRef.ts
|
|
1346
1414
|
function safeGetIframeDocument(iframe) {
|
|
@@ -1528,13 +1596,13 @@ function AgentCursor({
|
|
|
1528
1596
|
const [phase, setPhase] = useState9("idle");
|
|
1529
1597
|
const [ringBox, setRingBox] = useState9(null);
|
|
1530
1598
|
const [clickPulse, setClickPulse] = useState9(0);
|
|
1531
|
-
const cursorElRef =
|
|
1532
|
-
const pathRef =
|
|
1533
|
-
const prevCursorRef =
|
|
1534
|
-
const traceRef =
|
|
1535
|
-
const timersRef =
|
|
1536
|
-
const trackFrameRef =
|
|
1537
|
-
const glideFrameRef =
|
|
1599
|
+
const cursorElRef = useRef3(null);
|
|
1600
|
+
const pathRef = useRef3(null);
|
|
1601
|
+
const prevCursorRef = useRef3(null);
|
|
1602
|
+
const traceRef = useRef3(null);
|
|
1603
|
+
const timersRef = useRef3(new Set);
|
|
1604
|
+
const trackFrameRef = useRef3(null);
|
|
1605
|
+
const glideFrameRef = useRef3(null);
|
|
1538
1606
|
const clearTimers = () => {
|
|
1539
1607
|
for (const t of timersRef.current)
|
|
1540
1608
|
clearTimeout(t);
|
|
@@ -1650,7 +1718,7 @@ function AgentCursor({
|
|
|
1650
1718
|
});
|
|
1651
1719
|
return cancelAnimation;
|
|
1652
1720
|
}, [target, animated]);
|
|
1653
|
-
|
|
1721
|
+
useEffect10(() => {
|
|
1654
1722
|
if (!target || target.kind === "gesture" || phase === "idle")
|
|
1655
1723
|
return;
|
|
1656
1724
|
const track = () => {
|
|
@@ -1682,7 +1750,7 @@ function AgentCursor({
|
|
|
1682
1750
|
}
|
|
1683
1751
|
};
|
|
1684
1752
|
}, [target, phase]);
|
|
1685
|
-
|
|
1753
|
+
useEffect10(() => {
|
|
1686
1754
|
return () => {
|
|
1687
1755
|
traceRef.current?.cancel();
|
|
1688
1756
|
for (const t of timersRef.current)
|
|
@@ -1775,12 +1843,12 @@ function AgentCursor({
|
|
|
1775
1843
|
// src/components/AutoStartMedia.tsx
|
|
1776
1844
|
import { useConnectionState, useLocalParticipant as useLocalParticipant2 } from "@livekit/components-react/hooks";
|
|
1777
1845
|
import { ConnectionState, Track } from "livekit-client";
|
|
1778
|
-
import { useEffect as
|
|
1846
|
+
import { useEffect as useEffect11, useRef as useRef4 } from "react";
|
|
1779
1847
|
function AutoStartMedia({ pendingScreenStream }) {
|
|
1780
1848
|
const { localParticipant } = useLocalParticipant2();
|
|
1781
1849
|
const connectionState = useConnectionState();
|
|
1782
|
-
const didStartRef =
|
|
1783
|
-
|
|
1850
|
+
const didStartRef = useRef4(false);
|
|
1851
|
+
useEffect11(() => {
|
|
1784
1852
|
if (didStartRef.current)
|
|
1785
1853
|
return;
|
|
1786
1854
|
if (connectionState !== ConnectionState.Connected)
|
|
@@ -1805,7 +1873,7 @@ function AutoStartMedia({ pendingScreenStream }) {
|
|
|
1805
1873
|
// src/components/DomCapture.tsx
|
|
1806
1874
|
import { useConnectionState as useConnectionState2, useLocalParticipant as useLocalParticipant3 } from "@livekit/components-react/hooks";
|
|
1807
1875
|
import { ConnectionState as ConnectionState2, ScreenSharePresets, Track as Track2 } from "livekit-client";
|
|
1808
|
-
import { useEffect as
|
|
1876
|
+
import { useEffect as useEffect12, useRef as useRef5 } from "react";
|
|
1809
1877
|
|
|
1810
1878
|
// src/capture/a11yUtils.ts
|
|
1811
1879
|
var ROLE_BY_TAG = {
|
|
@@ -2713,8 +2781,8 @@ async function unpublishAndStopTrack(localParticipant, videoTrack) {
|
|
|
2713
2781
|
function DomCapture() {
|
|
2714
2782
|
const { localParticipant } = useLocalParticipant3();
|
|
2715
2783
|
const connectionState = useConnectionState2();
|
|
2716
|
-
const didStartRef =
|
|
2717
|
-
|
|
2784
|
+
const didStartRef = useRef5(false);
|
|
2785
|
+
useEffect12(() => {
|
|
2718
2786
|
if (didStartRef.current)
|
|
2719
2787
|
return;
|
|
2720
2788
|
if (connectionState !== ConnectionState2.Connected)
|
|
@@ -2824,7 +2892,7 @@ function DomCapture() {
|
|
|
2824
2892
|
|
|
2825
2893
|
// src/components/HighlightOverlay.tsx
|
|
2826
2894
|
import { useDataChannel } from "@livekit/components-react/hooks";
|
|
2827
|
-
import { useCallback as useCallback7, useEffect as
|
|
2895
|
+
import { useCallback as useCallback7, useEffect as useEffect13, useRef as useRef6 } from "react";
|
|
2828
2896
|
var HIGHLIGHT_AUTO_CLEAR_MS = 1e4;
|
|
2829
2897
|
var textDecoder = new TextDecoder;
|
|
2830
2898
|
function parseHighlightMessage(payload) {
|
|
@@ -2847,8 +2915,8 @@ function parseHighlightMessage(payload) {
|
|
|
2847
2915
|
}
|
|
2848
2916
|
}
|
|
2849
2917
|
function HighlightOverlay() {
|
|
2850
|
-
const targetRef =
|
|
2851
|
-
const autoClearRef =
|
|
2918
|
+
const targetRef = useRef6(null);
|
|
2919
|
+
const autoClearRef = useRef6(null);
|
|
2852
2920
|
const clear = useCallback7(() => {
|
|
2853
2921
|
if (autoClearRef.current)
|
|
2854
2922
|
clearTimeout(autoClearRef.current);
|
|
@@ -2880,7 +2948,7 @@ function HighlightOverlay() {
|
|
|
2880
2948
|
autoClearRef.current = setTimeout(clear, HIGHLIGHT_AUTO_CLEAR_MS);
|
|
2881
2949
|
}, [clear]);
|
|
2882
2950
|
useDataChannel(HIGHLIGHT_TOPIC, onHighlightMessage);
|
|
2883
|
-
|
|
2951
|
+
useEffect13(() => {
|
|
2884
2952
|
const onClick = (event) => {
|
|
2885
2953
|
const target = targetRef.current;
|
|
2886
2954
|
const node = event.target;
|
|
@@ -2890,26 +2958,26 @@ function HighlightOverlay() {
|
|
|
2890
2958
|
document.addEventListener("click", onClick, { capture: true });
|
|
2891
2959
|
return () => document.removeEventListener("click", onClick, { capture: true });
|
|
2892
2960
|
}, [clear]);
|
|
2893
|
-
|
|
2961
|
+
useEffect13(() => clear, [clear]);
|
|
2894
2962
|
return null;
|
|
2895
2963
|
}
|
|
2896
2964
|
|
|
2897
2965
|
// src/components/MinimizedBubble.tsx
|
|
2898
|
-
import { useContext as useContext5, useEffect as
|
|
2966
|
+
import { useContext as useContext5, useEffect as useEffect15, useRef as useRef8, useState as useState10 } from "react";
|
|
2899
2967
|
|
|
2900
2968
|
// src/hooks/useLauncherDrag.ts
|
|
2901
|
-
import { useEffect as
|
|
2969
|
+
import { useEffect as useEffect14, useRef as useRef7 } from "react";
|
|
2902
2970
|
import { flushSync } from "react-dom";
|
|
2903
2971
|
var DRAG_THRESHOLD_PX = 5;
|
|
2904
2972
|
function useLauncherDrag(containerRef, onDrop, followRefs, reportDragging) {
|
|
2905
|
-
const wasDraggedRef =
|
|
2906
|
-
const onDropRef =
|
|
2973
|
+
const wasDraggedRef = useRef7(false);
|
|
2974
|
+
const onDropRef = useRef7(onDrop);
|
|
2907
2975
|
onDropRef.current = onDrop;
|
|
2908
|
-
const followTargetsRef =
|
|
2976
|
+
const followTargetsRef = useRef7(followRefs);
|
|
2909
2977
|
followTargetsRef.current = followRefs;
|
|
2910
|
-
const reportDraggingRef =
|
|
2978
|
+
const reportDraggingRef = useRef7(reportDragging);
|
|
2911
2979
|
reportDraggingRef.current = reportDragging;
|
|
2912
|
-
|
|
2980
|
+
useEffect14(() => {
|
|
2913
2981
|
const el = containerRef.current;
|
|
2914
2982
|
if (!el)
|
|
2915
2983
|
return;
|
|
@@ -3242,7 +3310,7 @@ function WelcomeBubble({
|
|
|
3242
3310
|
onDismiss,
|
|
3243
3311
|
onClick
|
|
3244
3312
|
}) {
|
|
3245
|
-
|
|
3313
|
+
useEffect15(() => {
|
|
3246
3314
|
const timer = setTimeout(onDismiss, 5000);
|
|
3247
3315
|
return () => clearTimeout(timer);
|
|
3248
3316
|
}, [onDismiss]);
|
|
@@ -3289,10 +3357,10 @@ function MinimizedBubble({
|
|
|
3289
3357
|
const [goalsAutoHidden, setGoalsAutoHidden] = useState10(false);
|
|
3290
3358
|
const [isLauncherHovered, setIsLauncherHovered] = useState10(false);
|
|
3291
3359
|
const [visitHref, setVisitHref] = useState10(() => window.location.href);
|
|
3292
|
-
const revealedHrefRef =
|
|
3293
|
-
const hoverContainerRef =
|
|
3294
|
-
|
|
3295
|
-
|
|
3360
|
+
const revealedHrefRef = useRef8(null);
|
|
3361
|
+
const hoverContainerRef = useRef8(null);
|
|
3362
|
+
useEffect15(() => subscribeToLocationChange(() => setVisitHref(window.location.href)), []);
|
|
3363
|
+
useEffect15(() => {
|
|
3296
3364
|
const el = hoverContainerRef.current;
|
|
3297
3365
|
if (!el)
|
|
3298
3366
|
return;
|
|
@@ -3314,7 +3382,7 @@ function MinimizedBubble({
|
|
|
3314
3382
|
const onboardingModule = pillCandidates.find((module) => module.type === "onboarding");
|
|
3315
3383
|
const modulePills = onboardingModule ? [onboardingModule] : pillCandidates.slice(0, MAX_MODULE_PILLS).reverse();
|
|
3316
3384
|
const goalsEligible = adoptionGoals.length > 0 && !onboardingModule && hasResolvedModules;
|
|
3317
|
-
|
|
3385
|
+
useEffect15(() => {
|
|
3318
3386
|
if (!goalsEligible)
|
|
3319
3387
|
return;
|
|
3320
3388
|
if (revealedHrefRef.current === visitHref) {
|
|
@@ -3329,7 +3397,7 @@ function MinimizedBubble({
|
|
|
3329
3397
|
const matchedGoals = goalsEligible ? adoptionGoals.slice(0, MAX_GOAL_BUBBLES) : [];
|
|
3330
3398
|
const goalsHidden = goalsAutoHidden && !isLauncherHovered;
|
|
3331
3399
|
const [goalsUnmounted, setGoalsUnmounted] = useState10(false);
|
|
3332
|
-
|
|
3400
|
+
useEffect15(() => {
|
|
3333
3401
|
if (!goalsHidden) {
|
|
3334
3402
|
setGoalsUnmounted(false);
|
|
3335
3403
|
return;
|
|
@@ -3404,7 +3472,7 @@ function MinimizedBubble({
|
|
|
3404
3472
|
|
|
3405
3473
|
// src/components/PageActionHandler.tsx
|
|
3406
3474
|
import { useDataChannel as useDataChannel2 } from "@livekit/components-react/hooks";
|
|
3407
|
-
import { useCallback as useCallback8, useEffect as
|
|
3475
|
+
import { useCallback as useCallback8, useEffect as useEffect16, useRef as useRef9 } from "react";
|
|
3408
3476
|
var STEP_MAX_WAIT_MS = 5000;
|
|
3409
3477
|
var POST_ACTION_SETTLE_SNAPSHOT_MS = 300;
|
|
3410
3478
|
var textDecoder2 = new TextDecoder;
|
|
@@ -3621,11 +3689,11 @@ function labelFor(action) {
|
|
|
3621
3689
|
}
|
|
3622
3690
|
}
|
|
3623
3691
|
function PageActionHandler() {
|
|
3624
|
-
const mountedRef =
|
|
3625
|
-
const queueRef =
|
|
3626
|
-
const drainingRef =
|
|
3627
|
-
const settleTimerRef =
|
|
3628
|
-
const endStepRef =
|
|
3692
|
+
const mountedRef = useRef9(true);
|
|
3693
|
+
const queueRef = useRef9([]);
|
|
3694
|
+
const drainingRef = useRef9(false);
|
|
3695
|
+
const settleTimerRef = useRef9(null);
|
|
3696
|
+
const endStepRef = useRef9(null);
|
|
3629
3697
|
const runStep = useCallback8((action) => {
|
|
3630
3698
|
return new Promise((resolve) => {
|
|
3631
3699
|
if (action.type === "scroll_page") {
|
|
@@ -3733,7 +3801,7 @@ function PageActionHandler() {
|
|
|
3733
3801
|
queueRef.current.push(action);
|
|
3734
3802
|
drain();
|
|
3735
3803
|
}, [drain]);
|
|
3736
|
-
|
|
3804
|
+
useEffect16(() => {
|
|
3737
3805
|
mountedRef.current = true;
|
|
3738
3806
|
drainingRef.current = false;
|
|
3739
3807
|
return () => {
|
|
@@ -3745,7 +3813,7 @@ function PageActionHandler() {
|
|
|
3745
3813
|
setActionsBusy(false);
|
|
3746
3814
|
};
|
|
3747
3815
|
}, []);
|
|
3748
|
-
|
|
3816
|
+
useEffect16(() => {
|
|
3749
3817
|
return onActionsPausedChange((paused) => {
|
|
3750
3818
|
if (paused) {
|
|
3751
3819
|
clearCursorTarget("act");
|
|
@@ -3761,18 +3829,18 @@ function PageActionHandler() {
|
|
|
3761
3829
|
}
|
|
3762
3830
|
|
|
3763
3831
|
// src/components/SessionControlBar.tsx
|
|
3764
|
-
import { useContext as useContext6, useEffect as
|
|
3832
|
+
import { useContext as useContext6, useEffect as useEffect19 } from "react";
|
|
3765
3833
|
|
|
3766
3834
|
// src/hooks/useActionControl.ts
|
|
3767
3835
|
import { useLocalParticipant as useLocalParticipant4 } from "@livekit/components-react/hooks";
|
|
3768
|
-
import { useCallback as useCallback9, useEffect as
|
|
3836
|
+
import { useCallback as useCallback9, useEffect as useEffect17, useState as useState11 } from "react";
|
|
3769
3837
|
var textEncoder4 = new TextEncoder;
|
|
3770
3838
|
function useActionControl() {
|
|
3771
3839
|
const { localParticipant } = useLocalParticipant4();
|
|
3772
3840
|
const plan = usePlanUpdates();
|
|
3773
3841
|
const [busy, setBusy] = useState11(isActionsBusy);
|
|
3774
3842
|
const [actionsPaused2, setPaused] = useState11(false);
|
|
3775
|
-
|
|
3843
|
+
useEffect17(() => subscribeActionsBusy(setBusy), []);
|
|
3776
3844
|
const actionsActive = busy || plan?.state === "executing";
|
|
3777
3845
|
const togglePaused = useCallback9(async () => {
|
|
3778
3846
|
const next = !actionsPaused2;
|
|
@@ -3800,13 +3868,13 @@ function useAgentVoiceState() {
|
|
|
3800
3868
|
}
|
|
3801
3869
|
|
|
3802
3870
|
// src/hooks/useAudioLevelBars.ts
|
|
3803
|
-
import { useEffect as
|
|
3871
|
+
import { useEffect as useEffect18, useRef as useRef10, useState as useState12 } from "react";
|
|
3804
3872
|
var TALKING_LEVEL_THRESHOLD = 0.2;
|
|
3805
3873
|
var TALKING_HOLD_MS = 400;
|
|
3806
3874
|
function useAudioLevelBars(mediaStreamTrack, { barCount, idleHeightPx, maxGrowthPx, noiseGate }) {
|
|
3807
|
-
const barRefs =
|
|
3875
|
+
const barRefs = useRef10([]);
|
|
3808
3876
|
const [isTalking, setIsTalking] = useState12(false);
|
|
3809
|
-
|
|
3877
|
+
useEffect18(() => {
|
|
3810
3878
|
if (!mediaStreamTrack) {
|
|
3811
3879
|
for (const bar of barRefs.current) {
|
|
3812
3880
|
if (bar)
|
|
@@ -4062,7 +4130,7 @@ function SessionControlBar() {
|
|
|
4062
4130
|
const { state, mediaStreamTrack: agentMediaStreamTrack } = useAgentVoiceState();
|
|
4063
4131
|
const { actionsActive, actionsPaused: actionsPaused2, togglePaused } = useActionControl();
|
|
4064
4132
|
const { isHeld, countdown, toggle: togglePause } = useSessionHoldContext();
|
|
4065
|
-
|
|
4133
|
+
useEffect19(() => {
|
|
4066
4134
|
if (isHeld)
|
|
4067
4135
|
minimizePanel();
|
|
4068
4136
|
}, [isHeld, minimizePanel]);
|
|
@@ -4283,7 +4351,7 @@ function SessionControlBar() {
|
|
|
4283
4351
|
}
|
|
4284
4352
|
|
|
4285
4353
|
// src/components/ShadowHost.tsx
|
|
4286
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as
|
|
4354
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef11, useState as useState13 } from "react";
|
|
4287
4355
|
import { createPortal } from "react-dom";
|
|
4288
4356
|
import { jsx as jsx7, Fragment as Fragment2 } from "react/jsx-runtime";
|
|
4289
4357
|
var PROPERTIES_STYLE_ID = "skippr-tw-properties";
|
|
@@ -4300,7 +4368,7 @@ function hoistTailwindProperties(css) {
|
|
|
4300
4368
|
return css.replace(PROPERTY_RULE, "");
|
|
4301
4369
|
}
|
|
4302
4370
|
function ShadowHost({ children }) {
|
|
4303
|
-
const hostRef =
|
|
4371
|
+
const hostRef = useRef11(null);
|
|
4304
4372
|
const [shadowRoot, setShadowRoot] = useState13(null);
|
|
4305
4373
|
const css = `/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
|
|
4306
4374
|
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--skippr-font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--skippr-font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--skippr-color-red-50:oklch(97.1% .013 17.38);--skippr-color-red-100:oklch(93.6% .032 17.717);--skippr-color-red-200:oklch(88.5% .062 18.334);--skippr-color-red-300:oklch(80.8% .114 19.571);--skippr-color-red-400:oklch(70.4% .191 22.216);--skippr-color-red-500:oklch(63.7% .237 25.331);--skippr-color-red-600:oklch(57.7% .245 27.325);--skippr-color-red-700:oklch(50.5% .213 27.518);--skippr-color-amber-50:oklch(98.7% .022 95.277);--skippr-color-amber-100:oklch(96.2% .059 95.617);--skippr-color-amber-400:oklch(82.8% .189 84.429);--skippr-color-amber-700:oklch(55.5% .163 48.998);--skippr-color-amber-950:oklch(27.9% .077 45.635);--skippr-color-green-100:oklch(96.2% .044 156.743);--skippr-color-green-200:oklch(92.5% .084 155.995);--skippr-color-green-700:oklch(52.7% .154 150.069);--skippr-color-emerald-400:oklch(76.5% .177 163.223);--skippr-color-neutral-100:oklch(97% 0 0);--skippr-color-neutral-200:oklch(92.2% 0 0);--skippr-color-neutral-500:oklch(55.6% 0 0);--skippr-color-neutral-700:oklch(37.1% 0 0);--skippr-color-black:#000;--skippr-color-white:#fff;--skippr-spacing:.25rem;--skippr-text-xs:.75rem;--skippr-text-xs--line-height:calc(1/.75);--skippr-text-sm:.875rem;--skippr-text-sm--line-height:calc(1.25/.875);--skippr-font-weight-medium:500;--skippr-font-weight-semibold:600;--skippr-leading-tight:1.25;--skippr-leading-snug:1.375;--skippr-leading-relaxed:1.625;--skippr-ease-out:cubic-bezier(0,0,.2,1);--skippr-ease-in-out:cubic-bezier(.4,0,.2,1);--skippr-animate-spin:spin 1s linear infinite;--skippr-animate-ping:ping 1s cubic-bezier(0,0,.2,1)infinite;--skippr-animate-bounce:bounce 1s infinite;--skippr-blur-sm:8px;--skippr-default-transition-duration:.15s;--skippr-default-transition-timing-function:cubic-bezier(.4,0,.2,1);--skippr-default-font-family:var(--skippr-font-sans);--skippr-default-mono-font-family:var(--skippr-font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--skippr-default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--skippr-default-font-feature-settings,normal);font-variation-settings:var(--skippr-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--skippr-default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--skippr-default-mono-font-feature-settings,normal);font-variation-settings:var(--skippr-default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.skippr\\:pointer-events-none{pointer-events:none}.skippr\\:absolute{position:absolute}.skippr\\:fixed{position:fixed}.skippr\\:relative{position:relative}.skippr\\:sticky{position:sticky}.skippr\\:inset-0{inset:calc(var(--skippr-spacing)*0)}.skippr\\:inset-y-0{inset-block:calc(var(--skippr-spacing)*0)}.skippr\\:top-0{top:calc(var(--skippr-spacing)*0)}.skippr\\:top-1\\/2{top:50%}.skippr\\:top-full{top:100%}.skippr\\:-right-8{right:calc(var(--skippr-spacing)*-8)}.skippr\\:right-0{right:calc(var(--skippr-spacing)*0)}.skippr\\:right-3{right:calc(var(--skippr-spacing)*3)}.skippr\\:right-5{right:calc(var(--skippr-spacing)*5)}.skippr\\:right-6{right:calc(var(--skippr-spacing)*6)}.skippr\\:-bottom-1{bottom:calc(var(--skippr-spacing)*-1)}.skippr\\:-bottom-9{bottom:calc(var(--skippr-spacing)*-9)}.skippr\\:bottom-3{bottom:calc(var(--skippr-spacing)*3)}.skippr\\:bottom-20{bottom:calc(var(--skippr-spacing)*20)}.skippr\\:bottom-full{bottom:100%}.skippr\\:-left-8{left:calc(var(--skippr-spacing)*-8)}.skippr\\:left-0{left:calc(var(--skippr-spacing)*0)}.skippr\\:left-1\\/2{left:50%}.skippr\\:left-3{left:calc(var(--skippr-spacing)*3)}.skippr\\:left-5{left:calc(var(--skippr-spacing)*5)}.skippr\\:left-6{left:calc(var(--skippr-spacing)*6)}.skippr\\:z-10{z-index:10}.skippr\\:z-20{z-index:20}.skippr\\:z-\\[9998\\]{z-index:9998}.skippr\\:z-\\[9999\\]{z-index:9999}.skippr\\:order-first{order:-9999}.skippr\\:order-last{order:9999}.skippr\\:mx-auto{margin-inline:auto}.skippr\\:-mt-\\[5px\\]{margin-top:-5px}.skippr\\:-mt-\\[27px\\]{margin-top:-27px}.skippr\\:mt-0\\.5{margin-top:calc(var(--skippr-spacing)*.5)}.skippr\\:mt-1{margin-top:calc(var(--skippr-spacing)*1)}.skippr\\:mt-1\\.5{margin-top:calc(var(--skippr-spacing)*1.5)}.skippr\\:mt-2{margin-top:calc(var(--skippr-spacing)*2)}.skippr\\:mt-3{margin-top:calc(var(--skippr-spacing)*3)}.skippr\\:mt-3\\.5{margin-top:calc(var(--skippr-spacing)*3.5)}.skippr\\:mr-7{margin-right:calc(var(--skippr-spacing)*7)}.skippr\\:-mb-\\[5px\\]{margin-bottom:-5px}.skippr\\:mb-1\\.5{margin-bottom:calc(var(--skippr-spacing)*1.5)}.skippr\\:mb-2{margin-bottom:calc(var(--skippr-spacing)*2)}.skippr\\:mb-3{margin-bottom:calc(var(--skippr-spacing)*3)}.skippr\\:mb-4{margin-bottom:calc(var(--skippr-spacing)*4)}.skippr\\:ml-0\\.5{margin-left:calc(var(--skippr-spacing)*.5)}.skippr\\:ml-1{margin-left:calc(var(--skippr-spacing)*1)}.skippr\\:ml-7{margin-left:calc(var(--skippr-spacing)*7)}.skippr\\:flex{display:flex}.skippr\\:hidden{display:none}.skippr\\:inline-flex{display:inline-flex}.skippr\\:size-1{width:calc(var(--skippr-spacing)*1);height:calc(var(--skippr-spacing)*1)}.skippr\\:size-1\\.5{width:calc(var(--skippr-spacing)*1.5);height:calc(var(--skippr-spacing)*1.5)}.skippr\\:size-2{width:calc(var(--skippr-spacing)*2);height:calc(var(--skippr-spacing)*2)}.skippr\\:size-2\\.5{width:calc(var(--skippr-spacing)*2.5);height:calc(var(--skippr-spacing)*2.5)}.skippr\\:size-3{width:calc(var(--skippr-spacing)*3);height:calc(var(--skippr-spacing)*3)}.skippr\\:size-3\\.5{width:calc(var(--skippr-spacing)*3.5);height:calc(var(--skippr-spacing)*3.5)}.skippr\\:size-4{width:calc(var(--skippr-spacing)*4);height:calc(var(--skippr-spacing)*4)}.skippr\\:size-5{width:calc(var(--skippr-spacing)*5);height:calc(var(--skippr-spacing)*5)}.skippr\\:size-6{width:calc(var(--skippr-spacing)*6);height:calc(var(--skippr-spacing)*6)}.skippr\\:size-7{width:calc(var(--skippr-spacing)*7);height:calc(var(--skippr-spacing)*7)}.skippr\\:size-8{width:calc(var(--skippr-spacing)*8);height:calc(var(--skippr-spacing)*8)}.skippr\\:size-9{width:calc(var(--skippr-spacing)*9);height:calc(var(--skippr-spacing)*9)}.skippr\\:size-10{width:calc(var(--skippr-spacing)*10);height:calc(var(--skippr-spacing)*10)}.skippr\\:size-12{width:calc(var(--skippr-spacing)*12);height:calc(var(--skippr-spacing)*12)}.skippr\\:size-\\[5px\\]{width:5px;height:5px}.skippr\\:size-\\[38px\\]{width:38px;height:38px}.skippr\\:size-full{width:100%;height:100%}.skippr\\:h-0{height:calc(var(--skippr-spacing)*0)}.skippr\\:h-0\\.5{height:calc(var(--skippr-spacing)*.5)}.skippr\\:h-1{height:calc(var(--skippr-spacing)*1)}.skippr\\:h-1\\.5{height:calc(var(--skippr-spacing)*1.5)}.skippr\\:h-2{height:calc(var(--skippr-spacing)*2)}.skippr\\:h-3{height:calc(var(--skippr-spacing)*3)}.skippr\\:h-3\\.5{height:calc(var(--skippr-spacing)*3.5)}.skippr\\:h-4{height:calc(var(--skippr-spacing)*4)}.skippr\\:h-5{height:calc(var(--skippr-spacing)*5)}.skippr\\:h-6{height:calc(var(--skippr-spacing)*6)}.skippr\\:h-7{height:calc(var(--skippr-spacing)*7)}.skippr\\:h-8{height:calc(var(--skippr-spacing)*8)}.skippr\\:h-9{height:calc(var(--skippr-spacing)*9)}.skippr\\:h-10{height:calc(var(--skippr-spacing)*10)}.skippr\\:h-\\[18\\.5px\\]{height:18.5px}.skippr\\:h-\\[36px\\]{height:36px}.skippr\\:h-\\[38px\\]{height:38px}.skippr\\:h-\\[48px\\]{height:48px}.skippr\\:h-\\[54px\\]{height:54px}.skippr\\:h-full{height:100%}.skippr\\:min-h-0{min-height:calc(var(--skippr-spacing)*0)}.skippr\\:min-h-11{min-height:calc(var(--skippr-spacing)*11)}.skippr\\:w-0{width:calc(var(--skippr-spacing)*0)}.skippr\\:w-3\\.5{width:calc(var(--skippr-spacing)*3.5)}.skippr\\:w-4{width:calc(var(--skippr-spacing)*4)}.skippr\\:w-5{width:calc(var(--skippr-spacing)*5)}.skippr\\:w-6{width:calc(var(--skippr-spacing)*6)}.skippr\\:w-7{width:calc(var(--skippr-spacing)*7)}.skippr\\:w-8{width:calc(var(--skippr-spacing)*8)}.skippr\\:w-10{width:calc(var(--skippr-spacing)*10)}.skippr\\:w-40{width:calc(var(--skippr-spacing)*40)}.skippr\\:w-\\[2px\\]{width:2px}.skippr\\:w-\\[3px\\]{width:3px}.skippr\\:w-\\[15\\.4px\\]{width:15.4px}.skippr\\:w-\\[36px\\]{width:36px}.skippr\\:w-\\[50px\\]{width:50px}.skippr\\:w-full{width:100%}.skippr\\:max-w-64{max-width:calc(var(--skippr-spacing)*64)}.skippr\\:max-w-72{max-width:calc(var(--skippr-spacing)*72)}.skippr\\:max-w-\\[80\\%\\]{max-width:80%}.skippr\\:min-w-0{min-width:calc(var(--skippr-spacing)*0)}.skippr\\:min-w-11{min-width:calc(var(--skippr-spacing)*11)}.skippr\\:flex-1{flex:1}.skippr\\:shrink-0{flex-shrink:0}.skippr\\:origin-bottom-left{transform-origin:0 100%}.skippr\\:origin-bottom-right{transform-origin:100% 100%}.skippr\\:origin-center{transform-origin:50%}.skippr\\:origin-left{transform-origin:0}.skippr\\:origin-right{transform-origin:100%}.skippr\\:origin-top-left{transform-origin:0 0}.skippr\\:origin-top-right{transform-origin:100% 0}.skippr\\:-translate-x-1\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.skippr\\:-translate-x-3{--tw-translate-x:calc(var(--skippr-spacing)*-3);translate:var(--tw-translate-x)var(--tw-translate-y)}.skippr\\:-translate-x-7{--tw-translate-x:calc(var(--skippr-spacing)*-7);translate:var(--tw-translate-x)var(--tw-translate-y)}.skippr\\:translate-x-3{--tw-translate-x:calc(var(--skippr-spacing)*3);translate:var(--tw-translate-x)var(--tw-translate-y)}.skippr\\:translate-x-7{--tw-translate-x:calc(var(--skippr-spacing)*7);translate:var(--tw-translate-x)var(--tw-translate-y)}.skippr\\:scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x)var(--tw-scale-y)}.skippr\\:scale-95{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.skippr\\:scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.skippr\\:-rotate-90{rotate:-90deg}.skippr\\:rotate-45{rotate:45deg}.skippr\\:rotate-\\[225deg\\]{rotate:225deg}.skippr\\:\\[animation\\:skippr-agent-in_200ms_ease-out_240ms_both\\]{animation:.2s ease-out .24s both skippr-agent-in}.skippr\\:\\[animation\\:skippr-banner-look_2\\.4s_ease-in-out_infinite\\]{animation:2.4s ease-in-out infinite skippr-banner-look}.skippr\\:\\[animation\\:skippr-finger-tap_1\\.1s_ease-in-out_infinite\\]{animation:1.1s ease-in-out infinite skippr-finger-tap}.skippr\\:\\[animation\\:skippr-orb-in_320ms_cubic-bezier\\(0\\.34\\,1\\.3\\,0\\.64\\,1\\)\\]{animation:.32s cubic-bezier(.34,1.3,.64,1) skippr-orb-in}.skippr\\:\\[animation\\:skippr-stage-fade_240ms_ease-out\\]{animation:.24s ease-out skippr-stage-fade}.skippr\\:\\[animation\\:skippr-tip-in_360ms_cubic-bezier\\(0\\.34\\,1\\.3\\,0\\.64\\,1\\)_backwards\\]{animation:.36s cubic-bezier(.34,1.3,.64,1) backwards skippr-tip-in}.skippr\\:\\[animation\\:skippr-toolset-pop_280ms_cubic-bezier\\(0\\.22\\,1\\,0\\.36\\,1\\)\\]{animation:.28s cubic-bezier(.22,1,.36,1) skippr-toolset-pop}.skippr\\:\\[animation\\:skippr-toolset-pop_440ms_cubic-bezier\\(0\\.22\\,1\\,0\\.36\\,1\\)\\]{animation:.44s cubic-bezier(.22,1,.36,1) skippr-toolset-pop}.skippr\\:animate-\\[skippr-banner-look_2\\.4s_ease-in-out_infinite\\]{animation:2.4s ease-in-out infinite skippr-banner-look}.skippr\\:animate-\\[skippr-bubble-in_0\\.28s_ease-out\\]{animation:.28s ease-out skippr-bubble-in}.skippr\\:animate-\\[skippr-fade-in_0\\.3s_ease-out\\]{animation:.3s ease-out skippr-fade-in}.skippr\\:animate-\\[skippr-pill-content_0\\.22s_ease-out\\]{animation:.22s ease-out skippr-pill-content}.skippr\\:animate-\\[skippr-speak_1\\.1s_ease-in-out_0\\.3s_infinite\\]{animation:1.1s ease-in-out .3s infinite skippr-speak}.skippr\\:animate-\\[skippr-speak_1\\.1s_ease-in-out_0\\.6s_infinite\\]{animation:1.1s ease-in-out .6s infinite skippr-speak}.skippr\\:animate-\\[skippr-speak_1\\.1s_ease-in-out_0\\.15s_infinite\\]{animation:1.1s ease-in-out .15s infinite skippr-speak}.skippr\\:animate-\\[skippr-speak_1\\.1s_ease-in-out_0\\.45s_infinite\\]{animation:1.1s ease-in-out .45s infinite skippr-speak}.skippr\\:animate-\\[skippr-speak_1\\.1s_ease-in-out_infinite\\]{animation:1.1s ease-in-out infinite skippr-speak}.skippr\\:animate-bounce{animation:var(--skippr-animate-bounce)}.skippr\\:animate-ping{animation:var(--skippr-animate-ping)}.skippr\\:animate-skippr-annotation-pulse{animation:1.8s ease-in-out infinite skippr-annotation-pulse}.skippr\\:animate-skippr-click-ping{animation:.5s ease-out forwards skippr-click-ping}.skippr\\:animate-skippr-cursor-pop{animation:.22s ease-out skippr-cursor-pop}.skippr\\:animate-skippr-press{animation:.5s ease-in-out skippr-press}.skippr\\:animate-skippr-tab-fade{animation:.2s ease-out skippr-tab-fade}.skippr\\:animate-skippr-thinking-dot{animation:1.2s ease-in-out infinite skippr-thinking-dot}.skippr\\:animate-spin{animation:var(--skippr-animate-spin)}.skippr\\:cursor-default{cursor:default}.skippr\\:cursor-grab{cursor:grab}.skippr\\:cursor-not-allowed{cursor:not-allowed}.skippr\\:cursor-pointer{cursor:pointer}.skippr\\:touch-none{touch-action:none}.skippr\\:resize-none{resize:none}.skippr\\:flex-col{flex-direction:column}.skippr\\:flex-col-reverse{flex-direction:column-reverse}.skippr\\:items-center{align-items:center}.skippr\\:items-end{align-items:flex-end}.skippr\\:items-start{align-items:flex-start}.skippr\\:justify-between{justify-content:space-between}.skippr\\:justify-center{justify-content:center}.skippr\\:justify-end{justify-content:flex-end}.skippr\\:justify-start{justify-content:flex-start}.skippr\\:gap-0\\.5{gap:calc(var(--skippr-spacing)*.5)}.skippr\\:gap-1{gap:calc(var(--skippr-spacing)*1)}.skippr\\:gap-1\\.5{gap:calc(var(--skippr-spacing)*1.5)}.skippr\\:gap-2{gap:calc(var(--skippr-spacing)*2)}.skippr\\:gap-2\\.5{gap:calc(var(--skippr-spacing)*2.5)}.skippr\\:gap-3{gap:calc(var(--skippr-spacing)*3)}.skippr\\:gap-\\[2px\\]{gap:2px}.skippr\\:gap-\\[3px\\]{gap:3px}:where(.skippr\\:space-y-0\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--skippr-spacing)*.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--skippr-spacing)*.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.skippr\\:space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--skippr-spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--skippr-spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.skippr\\:space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--skippr-spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--skippr-spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.skippr\\:space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--skippr-spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--skippr-spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}.skippr\\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.skippr\\:overflow-hidden{overflow:hidden}.skippr\\:overflow-y-auto{overflow-y:auto}.skippr\\:rounded-2xl{border-radius:1.125rem}.skippr\\:rounded-\\[1rem\\]{border-radius:1rem}.skippr\\:rounded-\\[10px\\]{border-radius:10px}.skippr\\:rounded-\\[11px\\]{border-radius:11px}.skippr\\:rounded-\\[12px\\]{border-radius:12px}.skippr\\:rounded-\\[14px\\]{border-radius:14px}.skippr\\:rounded-\\[16px\\]{border-radius:16px}.skippr\\:rounded-\\[20px\\]{border-radius:20px}.skippr\\:rounded-full{border-radius:3.40282e38px}.skippr\\:rounded-lg{border-radius:.625rem}.skippr\\:rounded-md{border-radius:.5rem}.skippr\\:rounded-sm{border-radius:.375rem}.skippr\\:rounded-xl{border-radius:.875rem}.skippr\\:rounded-l-\\[18px\\]{border-top-left-radius:18px;border-bottom-left-radius:18px}.skippr\\:rounded-tl-md{border-top-left-radius:.5rem}.skippr\\:rounded-r-\\[18px\\]{border-top-right-radius:18px;border-bottom-right-radius:18px}.skippr\\:border{border-style:var(--tw-border-style);border-width:1px}.skippr\\:border-0{border-style:var(--tw-border-style);border-width:0}.skippr\\:border-2{border-style:var(--tw-border-style);border-width:2px}.skippr\\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.skippr\\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.skippr\\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.skippr\\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.skippr\\:border-\\[\\#2bc0ae\\]{border-color:#2bc0ae}.skippr\\:border-border,.skippr\\:border-input{border-color:oklch(92.3% .003 48.717)}.skippr\\:border-primary\\/20{border-color:oklab(29.9244% .0107414 -.0305411/.2)}.skippr\\:border-r-border{border-right-color:oklch(92.3% .003 48.717)}.skippr\\:border-l-border{border-left-color:oklch(92.3% .003 48.717)}.skippr\\:bg-\\[\\#2bc0ae\\]{background-color:#2bc0ae}.skippr\\:bg-\\[\\#2bc0ae\\]\\/50{background-color:oklab(72.9347% -.121518 -.00545585/.5)}.skippr\\:bg-amber-50{background-color:var(--skippr-color-amber-50)}.skippr\\:bg-amber-400{background-color:var(--skippr-color-amber-400)}.skippr\\:bg-background{background-color:oklch(100% 0 0)}.skippr\\:bg-black\\/\\[0\\.07\\]{background-color:var(--skippr-color-black)}@supports (color:color-mix(in lab, red, red)){.skippr\\:bg-black\\/\\[0\\.07\\]{background-color:color-mix(in oklab,var(--skippr-color-black)7.0%,transparent)}}.skippr\\:bg-bubble{background-color:#2d2b3d}.skippr\\:bg-bubble\\/95{background-color:oklab(29.9244% .0107414 -.0305411/.95)}.skippr\\:bg-card{background-color:oklch(100% 0 0)}.skippr\\:bg-current{background-color:currentColor}.skippr\\:bg-destructive{background-color:#d94f4f}.skippr\\:bg-emerald-400{background-color:var(--skippr-color-emerald-400)}.skippr\\:bg-foreground{background-color:oklch(14.7% .004 49.25)}.skippr\\:bg-green-100{background-color:var(--skippr-color-green-100)}.skippr\\:bg-launcher{background-color:#2d2d3f}.skippr\\:bg-muted-foreground\\/20{background-color:oklab(55.3% .00687528 .0110332/.2)}.skippr\\:bg-muted-foreground\\/40{background-color:oklab(55.3% .00687528 .0110332/.4)}.skippr\\:bg-muted\\/50{background-color:oklab(97% -.000282743 .000959196/.5)}.skippr\\:bg-neutral-100{background-color:var(--skippr-color-neutral-100)}.skippr\\:bg-primary{background-color:#2d2b3d}.skippr\\:bg-primary-foreground\\/20{background-color:oklab(100% 0 5.96046e-8/.2)}.skippr\\:bg-primary\\/10{background-color:oklab(29.9244% .0107414 -.0305411/.1)}.skippr\\:bg-red-50{background-color:var(--skippr-color-red-50)}.skippr\\:bg-red-100{background-color:var(--skippr-color-red-100)}.skippr\\:bg-red-400{background-color:var(--skippr-color-red-400)}.skippr\\:bg-red-500{background-color:var(--skippr-color-red-500)}.skippr\\:bg-secondary{background-color:#ffdfb5}.skippr\\:bg-transparent{background-color:#0000}.skippr\\:bg-white,.skippr\\:bg-white\\/15{background-color:var(--skippr-color-white)}@supports (color:color-mix(in lab, red, red)){.skippr\\:bg-white\\/15{background-color:color-mix(in oklab,var(--skippr-color-white)15%,transparent)}}.skippr\\:fill-brand{fill:#2bc0ae}.skippr\\:fill-primary\\/30{fill:oklab(29.9244% .0107414 -.0305411/.3)}.skippr\\:stroke-black\\/15{stroke:var(--skippr-color-black)}@supports (color:color-mix(in lab, red, red)){.skippr\\:stroke-black\\/15{stroke:color-mix(in oklab,var(--skippr-color-black)15%,transparent)}}.skippr\\:stroke-bubble{stroke:#2d2b3d}.skippr\\:p-0{padding:calc(var(--skippr-spacing)*0)}.skippr\\:p-0\\.5{padding:calc(var(--skippr-spacing)*.5)}.skippr\\:p-1\\.5{padding:calc(var(--skippr-spacing)*1.5)}.skippr\\:p-2{padding:calc(var(--skippr-spacing)*2)}.skippr\\:p-3{padding:calc(var(--skippr-spacing)*3)}.skippr\\:p-3\\.5{padding:calc(var(--skippr-spacing)*3.5)}.skippr\\:p-4{padding:calc(var(--skippr-spacing)*4)}.skippr\\:px-1{padding-inline:calc(var(--skippr-spacing)*1)}.skippr\\:px-1\\.5{padding-inline:calc(var(--skippr-spacing)*1.5)}.skippr\\:px-2{padding-inline:calc(var(--skippr-spacing)*2)}.skippr\\:px-2\\.5{padding-inline:calc(var(--skippr-spacing)*2.5)}.skippr\\:px-3{padding-inline:calc(var(--skippr-spacing)*3)}.skippr\\:px-4{padding-inline:calc(var(--skippr-spacing)*4)}.skippr\\:px-6{padding-inline:calc(var(--skippr-spacing)*6)}.skippr\\:px-8{padding-inline:calc(var(--skippr-spacing)*8)}.skippr\\:py-0\\.5{padding-block:calc(var(--skippr-spacing)*.5)}.skippr\\:py-1{padding-block:calc(var(--skippr-spacing)*1)}.skippr\\:py-1\\.5{padding-block:calc(var(--skippr-spacing)*1.5)}.skippr\\:py-2{padding-block:calc(var(--skippr-spacing)*2)}.skippr\\:py-2\\.5{padding-block:calc(var(--skippr-spacing)*2.5)}.skippr\\:py-3{padding-block:calc(var(--skippr-spacing)*3)}.skippr\\:py-4{padding-block:calc(var(--skippr-spacing)*4)}.skippr\\:py-6{padding-block:calc(var(--skippr-spacing)*6)}.skippr\\:pt-1\\.5{padding-top:calc(var(--skippr-spacing)*1.5)}.skippr\\:pr-2\\.5{padding-right:calc(var(--skippr-spacing)*2.5)}.skippr\\:pr-3{padding-right:calc(var(--skippr-spacing)*3)}.skippr\\:pb-2{padding-bottom:calc(var(--skippr-spacing)*2)}.skippr\\:pl-1\\.5{padding-left:calc(var(--skippr-spacing)*1.5)}.skippr\\:pl-2\\.5{padding-left:calc(var(--skippr-spacing)*2.5)}.skippr\\:pl-3\\.5{padding-left:calc(var(--skippr-spacing)*3.5)}.skippr\\:text-center{text-align:center}.skippr\\:text-left{text-align:left}.skippr\\:font-mono{font-family:var(--skippr-font-mono)}.skippr\\:text-sm{font-size:var(--skippr-text-sm);line-height:var(--tw-leading,var(--skippr-text-sm--line-height))}.skippr\\:text-xs{font-size:var(--skippr-text-xs);line-height:var(--tw-leading,var(--skippr-text-xs--line-height))}.skippr\\:text-\\[10px\\]{font-size:10px}.skippr\\:text-\\[11px\\]{font-size:11px}.skippr\\:text-\\[13px\\]{font-size:13px}.skippr\\:leading-5{--tw-leading:calc(var(--skippr-spacing)*5);line-height:calc(var(--skippr-spacing)*5)}.skippr\\:leading-relaxed{--tw-leading:var(--skippr-leading-relaxed);line-height:var(--skippr-leading-relaxed)}.skippr\\:leading-snug{--tw-leading:var(--skippr-leading-snug);line-height:var(--skippr-leading-snug)}.skippr\\:leading-tight{--tw-leading:var(--skippr-leading-tight);line-height:var(--skippr-leading-tight)}.skippr\\:font-medium{--tw-font-weight:var(--skippr-font-weight-medium);font-weight:var(--skippr-font-weight-medium)}.skippr\\:font-semibold{--tw-font-weight:var(--skippr-font-weight-semibold);font-weight:var(--skippr-font-weight-semibold)}.skippr\\:whitespace-nowrap{white-space:nowrap}.skippr\\:text-\\[\\#2bc0ae\\]{color:#2bc0ae}.skippr\\:text-amber-700{color:var(--skippr-color-amber-700)}.skippr\\:text-amber-950{color:var(--skippr-color-amber-950)}.skippr\\:text-background{color:oklch(100% 0 0)}.skippr\\:text-black{color:var(--skippr-color-black)}.skippr\\:text-bubble{color:#2d2b3d}.skippr\\:text-chart-3{color:oklch(66.6% .179 58.318)}.skippr\\:text-destructive{color:#d94f4f}.skippr\\:text-foreground{color:oklch(14.7% .004 49.25)}.skippr\\:text-green-700{color:var(--skippr-color-green-700)}.skippr\\:text-muted-foreground{color:oklch(55.3% .013 58.071)}.skippr\\:text-muted-foreground\\/30{color:oklab(55.3% .00687528 .0110332/.3)}.skippr\\:text-muted-foreground\\/40{color:oklab(55.3% .00687528 .0110332/.4)}.skippr\\:text-muted-foreground\\/60{color:oklab(55.3% .00687528 .0110332/.6)}.skippr\\:text-muted-foreground\\/70{color:oklab(55.3% .00687528 .0110332/.7)}.skippr\\:text-neutral-500{color:var(--skippr-color-neutral-500)}.skippr\\:text-neutral-700{color:var(--skippr-color-neutral-700)}.skippr\\:text-primary{color:#2d2b3d}.skippr\\:text-primary-foreground{color:#fff}.skippr\\:text-primary-foreground\\/70{color:oklab(100% 0 5.96046e-8/.7)}.skippr\\:text-red-400{color:var(--skippr-color-red-400)}.skippr\\:text-red-600{color:var(--skippr-color-red-600)}.skippr\\:text-red-700{color:var(--skippr-color-red-700)}.skippr\\:text-secondary-foreground{color:#613700}.skippr\\:text-white{color:var(--skippr-color-white)}.skippr\\:capitalize{text-transform:capitalize}.skippr\\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.skippr\\:line-through{text-decoration-line:line-through}.skippr\\:placeholder-muted-foreground::placeholder{color:oklch(55.3% .013 58.071)}.skippr\\:opacity-0{opacity:0}.skippr\\:opacity-40{opacity:.4}.skippr\\:opacity-75{opacity:.75}.skippr\\:opacity-100{opacity:1}.skippr\\:shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-\\[-6px_8px_30px_rgba\\(15\\,18\\,26\\,0\\.32\\)\\]{--tw-shadow:-6px 8px 30px var(--tw-shadow-color,#0f121a52);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-\\[0_4px_12px_rgba\\(0\\,0\\,0\\,0\\.12\\)\\]{--tw-shadow:0 4px 12px var(--tw-shadow-color,#0000001f);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-\\[0_4px_14px_rgba\\(239\\,68\\,68\\,0\\.45\\)\\]{--tw-shadow:0 4px 14px var(--tw-shadow-color,#ef444473);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-\\[0_4px_16px_rgba\\(45\\,43\\,61\\,0\\.45\\)\\,0_2px_4px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:0 4px 16px var(--tw-shadow-color,#2d2b3d73),0 2px 4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-\\[0_8px_24px_rgba\\(0\\,0\\,0\\,0\\.18\\)\\]{--tw-shadow:0 8px 24px var(--tw-shadow-color,#0000002e);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-\\[0_8px_24px_rgba\\(45\\,43\\,61\\,0\\.35\\)\\]{--tw-shadow:0 8px 24px var(--tw-shadow-color,#2d2b3d59);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-\\[0_8px_30px_rgba\\(0\\,0\\,0\\,0\\.16\\)\\,0_4px_12px_rgba\\(0\\,0\\,0\\,0\\.08\\)\\]{--tw-shadow:0 8px 30px var(--tw-shadow-color,#00000029),0 4px 12px var(--tw-shadow-color,#00000014);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-\\[0_10px_32px_rgba\\(0\\,0\\,0\\,0\\.18\\)\\]{--tw-shadow:0 10px 32px var(--tw-shadow-color,#0000002e);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:ring-1{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:ring-black\\/5{--tw-ring-color:var(--skippr-color-black)}@supports (color:color-mix(in lab, red, red)){.skippr\\:ring-black\\/5{--tw-ring-color:color-mix(in oklab,var(--skippr-color-black)5%,transparent)}}.skippr\\:ring-brand{--tw-ring-color:#2bc0ae}.skippr\\:ring-foreground\\/10{--tw-ring-color:oklab(14.7% .00261104 .00303026/.1)}.skippr\\:ring-white\\/30{--tw-ring-color:var(--skippr-color-white)}@supports (color:color-mix(in lab, red, red)){.skippr\\:ring-white\\/30{--tw-ring-color:color-mix(in oklab,var(--skippr-color-white)30%,transparent)}}.skippr\\:ring-offset-background{--tw-ring-offset-color:oklch(100% 0 0)}.skippr\\:drop-shadow-\\[0_2px_5px_rgba\\(0\\,0\\,0\\,0\\.4\\)\\]{--tw-drop-shadow-size:drop-shadow(0 2px 5px var(--tw-drop-shadow-color,#0006));--tw-drop-shadow:var(--tw-drop-shadow-size);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.skippr\\:backdrop-blur-sm{--tw-backdrop-blur:blur(var(--skippr-blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.skippr\\:transition-\\[height\\]{transition-property:height;transition-timing-function:var(--tw-ease,var(--skippr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--skippr-default-transition-duration))}.skippr\\:transition-\\[opacity\\,transform\\,height\\]{transition-property:opacity,transform,height;transition-timing-function:var(--tw-ease,var(--skippr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--skippr-default-transition-duration))}.skippr\\:transition-\\[width\\,margin\\]{transition-property:width,margin;transition-timing-function:var(--tw-ease,var(--skippr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--skippr-default-transition-duration))}.skippr\\:transition-\\[width\\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--skippr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--skippr-default-transition-duration))}.skippr\\:transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--skippr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--skippr-default-transition-duration))}.skippr\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--skippr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--skippr-default-transition-duration))}.skippr\\:transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--skippr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--skippr-default-transition-duration))}.skippr\\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--skippr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--skippr-default-transition-duration))}.skippr\\:duration-75{--tw-duration:75ms;transition-duration:75ms}.skippr\\:duration-150{--tw-duration:.15s;transition-duration:.15s}.skippr\\:duration-200{--tw-duration:.2s;transition-duration:.2s}.skippr\\:duration-300{--tw-duration:.3s;transition-duration:.3s}.skippr\\:duration-\\[400ms\\]{--tw-duration:.4s;transition-duration:.4s}.skippr\\:ease-\\[cubic-bezier\\(0\\.22\\,1\\,0\\.36\\,1\\)\\]{--tw-ease:cubic-bezier(.22,1,.36,1);transition-timing-function:cubic-bezier(.22,1,.36,1)}.skippr\\:ease-in-out{--tw-ease:var(--skippr-ease-in-out);transition-timing-function:var(--skippr-ease-in-out)}.skippr\\:ease-out{--tw-ease:var(--skippr-ease-out);transition-timing-function:var(--skippr-ease-out)}.skippr\\:outline-none{--tw-outline-style:none;outline-style:none}.skippr\\:select-none{-webkit-user-select:none;user-select:none}.skippr\\:\\[animation-delay\\:0ms\\]{animation-delay:0s}.skippr\\:\\[animation-delay\\:150ms\\]{animation-delay:.15s}.skippr\\:\\[animation-delay\\:200ms\\]{animation-delay:.2s}.skippr\\:\\[animation-delay\\:300ms\\]{animation-delay:.3s}.skippr\\:\\[animation-delay\\:400ms\\]{animation-delay:.4s}.skippr\\:\\[overflow-anchor\\:none\\]{overflow-anchor:none}.skippr\\:group-focus-within\\:scale-100:is(:where(.skippr\\:group):focus-within *){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.skippr\\:group-focus-within\\:opacity-100:is(:where(.skippr\\:group):focus-within *){opacity:1}@media (hover:hover){.skippr\\:group-hover\\:scale-100:is(:where(.skippr\\:group):hover *){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.skippr\\:group-hover\\:text-red-300:is(:where(.skippr\\:group):hover *){color:var(--skippr-color-red-300)}.skippr\\:group-hover\\:text-white\\/80:is(:where(.skippr\\:group):hover *){color:var(--skippr-color-white)}@supports (color:color-mix(in lab, red, red)){.skippr\\:group-hover\\:text-white\\/80:is(:where(.skippr\\:group):hover *){color:color-mix(in oklab,var(--skippr-color-white)80%,transparent)}}.skippr\\:group-hover\\:opacity-100:is(:where(.skippr\\:group):hover *){opacity:1}}.skippr\\:placeholder\\:text-muted-foreground::placeholder{color:oklch(55.3% .013 58.071)}@media (hover:hover){.skippr\\:hover\\:-translate-y-0\\.5:hover{--tw-translate-y:calc(var(--skippr-spacing)*-.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.skippr\\:hover\\:bg-\\[\\#3a384b\\]:hover{background-color:#3a384b}.skippr\\:hover\\:bg-accent:hover{background-color:#e7e5e4}.skippr\\:hover\\:bg-amber-100:hover{background-color:var(--skippr-color-amber-100)}.skippr\\:hover\\:bg-bubble:hover{background-color:#2d2b3d}.skippr\\:hover\\:bg-destructive\\/90:hover{background-color:oklab(61.4357% .15892 .0698893/.9)}.skippr\\:hover\\:bg-green-200:hover{background-color:var(--skippr-color-green-200)}.skippr\\:hover\\:bg-muted:hover{background-color:oklch(97% .001 106.424)}.skippr\\:hover\\:bg-neutral-100:hover{background-color:var(--skippr-color-neutral-100)}.skippr\\:hover\\:bg-neutral-200:hover{background-color:var(--skippr-color-neutral-200)}.skippr\\:hover\\:bg-primary\\/90:hover{background-color:oklab(29.9244% .0107414 -.0305411/.9)}.skippr\\:hover\\:bg-red-200:hover{background-color:var(--skippr-color-red-200)}.skippr\\:hover\\:bg-red-600:hover{background-color:var(--skippr-color-red-600)}.skippr\\:hover\\:bg-secondary\\/80:hover{background-color:oklab(91.9963% .0175391 .0626889/.8)}.skippr\\:hover\\:bg-white\\/10:hover{background-color:var(--skippr-color-white)}@supports (color:color-mix(in lab, red, red)){.skippr\\:hover\\:bg-white\\/10:hover{background-color:color-mix(in oklab,var(--skippr-color-white)10%,transparent)}}.skippr\\:hover\\:text-accent-foreground:hover{color:oklch(21.6% .006 56.043)}.skippr\\:hover\\:text-foreground:hover{color:oklch(14.7% .004 49.25)}.skippr\\:hover\\:text-primary-foreground:hover{color:#fff}.skippr\\:hover\\:brightness-110:hover{--tw-brightness:brightness(110%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}}.skippr\\:focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.skippr\\:focus-visible\\:ring-brand:focus-visible{--tw-ring-color:#2bc0ae}.skippr\\:focus-visible\\:ring-bubble\\/60:focus-visible{--tw-ring-color:oklab(29.9244% .0107414 -.0305411/.6)}.skippr\\:focus-visible\\:ring-ring:focus-visible{--tw-ring-color:oklch(70.9% .01 56.259)}.skippr\\:focus-visible\\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.skippr\\:focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.skippr\\:active\\:translate-y-0:active{--tw-translate-y:calc(var(--skippr-spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.skippr\\:disabled\\:pointer-events-none:disabled{pointer-events:none}.skippr\\:disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.skippr\\:disabled\\:opacity-50:disabled{opacity:.5}.skippr\\:disabled\\:opacity-60:disabled{opacity:.6}@media (prefers-reduced-motion:reduce){.skippr\\:motion-reduce\\:hidden{display:none}}.skippr\\:\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.skippr\\:\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.skippr\\:\\[\\&_svg\\:not\\(\\[class\\*\\=\\'size-\\'\\]\\)\\]\\:size-4 svg:not([class*=size-]){width:calc(var(--skippr-spacing)*4);height:calc(var(--skippr-spacing)*4)}}@keyframes skippr-tap{0%{transform:scale(1)}45%{transform:scale(.7)}to{transform:scale(1)}}@keyframes skippr-press{0%{transform:scale(1)}55%{transform:scale(1)}85%{transform:scale(.68)}to{transform:scale(1)}}@keyframes skippr-cursor-pop{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}@keyframes skippr-click-ping{0%{opacity:.9;transform:translate(-50%,-50%)scale(.4)}to{opacity:0;transform:translate(-50%,-50%)scale(2.4)}}@keyframes skippr-tab-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes skippr-speak{0%,to{opacity:.6;transform:scaleY(.4)}50%{opacity:1;transform:scaleY(1)}}@keyframes skippr-thinking-dot{0%,80%,to{opacity:.2;transform:translateY(0)}40%{opacity:1;transform:translateY(-2px)}}@keyframes skippr-pulse-ring{0%,to{box-shadow:0 0 #2d2b3d66}50%{box-shadow:0 0 0 10px #2d2b3d00}}@keyframes skippr-annotation-pulse{0%,to{box-shadow:0 0 #2bc0ae80}50%{box-shadow:0 0 0 6px #2bc0ae00}}@keyframes skippr-speak-ripple{0%{opacity:.6;transform:scale(1)}to{opacity:0;transform:scale(1.8)}}@keyframes skippr-bar{0%,to{transform:scaleY(.35)}50%{transform:scaleY(1)}}@keyframes skippr-breathe{0%,to{opacity:.85;transform:scale(1)}50%{opacity:1;transform:scale(1.08)}}@keyframes skippr-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes skippr-wave{0%,to{opacity:.4;transform:scaleY(.4)}50%{opacity:1;transform:scaleY(1)}}@keyframes skippr-bubble-in{0%{opacity:0;transform:translateY(12px)scale(.96)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes skippr-tip-in{0%{opacity:0;transform:translateY(14px)scale(.96)}60%{opacity:1;transform:translateY(-2px)scale(1.01)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes skippr-pill-content{0%{opacity:0;transform:scale(.92)}to{opacity:1;transform:scale(1)}}@keyframes skippr-banner-look{0%,to{transform:translate(0)}25%{transform:translate(-2px)}75%{transform:translate(2px)}}@keyframes skippr-finger-tap{0%,to{transform:translateY(0)rotate(0)}50%{transform:translateY(2px)rotate(-6deg)}}@keyframes skippr-toolset-pop{0%{opacity:0;transform:scale(.85)}to{opacity:1;transform:scale(1)}}@keyframes skippr-stage-fade{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}@keyframes skippr-agent-in{0%{opacity:0;transform:scale(.6)}to{opacity:1;transform:scale(1)}}@keyframes skippr-orb-in{0%{opacity:0;transform:scale(.6)}to{opacity:1;transform:scale(1)}}.skippr-no-scrollbar{scrollbar-width:none;-ms-overflow-style:none}.skippr-no-scrollbar::-webkit-scrollbar{display:none}:host{color:var(--color-foreground)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}`;
|
|
@@ -4328,14 +4396,14 @@ function ShadowHost({ children }) {
|
|
|
4328
4396
|
}
|
|
4329
4397
|
|
|
4330
4398
|
// src/components/Sidebar.tsx
|
|
4331
|
-
import { useContext as useContext11, useEffect as
|
|
4399
|
+
import { useContext as useContext11, useEffect as useEffect26 } from "react";
|
|
4332
4400
|
|
|
4333
4401
|
// src/hooks/useCombinedMessages.ts
|
|
4334
|
-
import { useContext as useContext7, useMemo as
|
|
4402
|
+
import { useContext as useContext7, useMemo as useMemo6 } from "react";
|
|
4335
4403
|
|
|
4336
4404
|
// src/hooks/useChatMessages.ts
|
|
4337
4405
|
import { useChat, useLocalParticipant as useLocalParticipant7 } from "@livekit/components-react/hooks";
|
|
4338
|
-
import { useMemo as
|
|
4406
|
+
import { useMemo as useMemo4 } from "react";
|
|
4339
4407
|
|
|
4340
4408
|
// src/lib/filterSystemMessages.ts
|
|
4341
4409
|
var SYSTEM_MESSAGE_PATTERN = /^\[\w+\]$/;
|
|
@@ -4348,7 +4416,7 @@ function useChatMessages() {
|
|
|
4348
4416
|
const { chatMessages: rawMessages, send, isSending } = useChat();
|
|
4349
4417
|
const { localParticipant } = useLocalParticipant7();
|
|
4350
4418
|
const localIdentity = localParticipant.identity;
|
|
4351
|
-
const chatMessages =
|
|
4419
|
+
const chatMessages = useMemo4(() => {
|
|
4352
4420
|
const sortedMessages = rawMessages.map((msg) => ({
|
|
4353
4421
|
id: msg.id,
|
|
4354
4422
|
role: msg.from?.identity === localIdentity ? "user" : "assistant",
|
|
@@ -4363,12 +4431,12 @@ function useChatMessages() {
|
|
|
4363
4431
|
|
|
4364
4432
|
// src/hooks/useStreamingTranscript.ts
|
|
4365
4433
|
import { useLocalParticipant as useLocalParticipant8, useTranscriptions } from "@livekit/components-react/hooks";
|
|
4366
|
-
import { useMemo as
|
|
4434
|
+
import { useMemo as useMemo5 } from "react";
|
|
4367
4435
|
function useStreamingTranscript() {
|
|
4368
4436
|
const transcriptions = useTranscriptions();
|
|
4369
4437
|
const { localParticipant } = useLocalParticipant8();
|
|
4370
4438
|
const localIdentity = localParticipant.identity;
|
|
4371
|
-
const transcriptMessages =
|
|
4439
|
+
const transcriptMessages = useMemo5(() => filterSystemMessages(transcriptions.filter((stream) => stream.text.trim().length > 0).map((stream) => ({
|
|
4372
4440
|
id: stream.streamInfo.id,
|
|
4373
4441
|
role: stream.participantInfo.identity === localIdentity ? "user" : "assistant",
|
|
4374
4442
|
content: stream.text,
|
|
@@ -4400,14 +4468,14 @@ function useCombinedMessages() {
|
|
|
4400
4468
|
const { chatMessages, sendChatMessage, isSendingChat } = useChatMessages();
|
|
4401
4469
|
const { state: agentState } = useAgentVoiceState();
|
|
4402
4470
|
const historyMessages = useContext7(LiveAgentContext)?.historyMessages ?? [];
|
|
4403
|
-
const liveMessages =
|
|
4471
|
+
const liveMessages = useMemo6(() => {
|
|
4404
4472
|
if (chatMessages.length === 0)
|
|
4405
4473
|
return transcriptMessages;
|
|
4406
4474
|
if (transcriptMessages.length === 0)
|
|
4407
4475
|
return chatMessages;
|
|
4408
4476
|
return mergeChatsIntoTranscripts(transcriptMessages, chatMessages);
|
|
4409
4477
|
}, [transcriptMessages, chatMessages]);
|
|
4410
|
-
const allMessages =
|
|
4478
|
+
const allMessages = useMemo6(() => {
|
|
4411
4479
|
if (historyMessages.length === 0)
|
|
4412
4480
|
return liveMessages;
|
|
4413
4481
|
const seenIds = new Set(liveMessages.map((message) => message.id));
|
|
@@ -4417,7 +4485,7 @@ function useCombinedMessages() {
|
|
|
4417
4485
|
}
|
|
4418
4486
|
|
|
4419
4487
|
// src/hooks/usePhaseUpdates.ts
|
|
4420
|
-
import { useCallback as useCallback11, useContext as useContext8, useEffect as
|
|
4488
|
+
import { useCallback as useCallback11, useContext as useContext8, useEffect as useEffect20 } from "react";
|
|
4421
4489
|
function parsePhases(json) {
|
|
4422
4490
|
try {
|
|
4423
4491
|
const data = JSON.parse(json);
|
|
@@ -4431,7 +4499,7 @@ function usePhaseUpdates() {
|
|
|
4431
4499
|
const parse = useCallback11(parsePhases, []);
|
|
4432
4500
|
const livePhases = useAgentState("phases", parse, []);
|
|
4433
4501
|
const ctx = useContext8(LiveAgentContext);
|
|
4434
|
-
|
|
4502
|
+
useEffect20(() => {
|
|
4435
4503
|
if (livePhases.length > 0)
|
|
4436
4504
|
ctx?.setPhasesSnapshot(livePhases);
|
|
4437
4505
|
}, [livePhases, ctx?.setPhasesSnapshot]);
|
|
@@ -4440,7 +4508,7 @@ function usePhaseUpdates() {
|
|
|
4440
4508
|
}
|
|
4441
4509
|
|
|
4442
4510
|
// src/hooks/useSessionRemaining.ts
|
|
4443
|
-
import { useEffect as
|
|
4511
|
+
import { useEffect as useEffect21, useRef as useRef12, useState as useState14 } from "react";
|
|
4444
4512
|
|
|
4445
4513
|
// src/lib/format.ts
|
|
4446
4514
|
function formatTime(seconds) {
|
|
@@ -4456,9 +4524,9 @@ function parseNumber(s) {
|
|
|
4456
4524
|
// src/hooks/useSessionRemaining.ts
|
|
4457
4525
|
function useSessionRemaining() {
|
|
4458
4526
|
const maxCallDuration = useAgentState("maxCallDuration", parseNumber, null);
|
|
4459
|
-
const endTimeRef =
|
|
4527
|
+
const endTimeRef = useRef12(null);
|
|
4460
4528
|
const [remaining, setRemaining] = useState14(null);
|
|
4461
|
-
|
|
4529
|
+
useEffect21(() => {
|
|
4462
4530
|
if (maxCallDuration === null || endTimeRef.current !== null)
|
|
4463
4531
|
return;
|
|
4464
4532
|
const endTime = Date.now() + maxCallDuration * 1000;
|
|
@@ -4475,13 +4543,13 @@ function useSessionRemaining() {
|
|
|
4475
4543
|
}
|
|
4476
4544
|
|
|
4477
4545
|
// src/components/ChatHeader.tsx
|
|
4478
|
-
import { useContext as useContext10, useRef as
|
|
4546
|
+
import { useContext as useContext10, useRef as useRef14 } from "react";
|
|
4479
4547
|
|
|
4480
4548
|
// src/hooks/useElapsedSeconds.ts
|
|
4481
|
-
import { useEffect as
|
|
4549
|
+
import { useEffect as useEffect22, useState as useState15 } from "react";
|
|
4482
4550
|
function useElapsedSeconds(isRunning) {
|
|
4483
4551
|
const [elapsed, setElapsed] = useState15(0);
|
|
4484
|
-
|
|
4552
|
+
useEffect22(() => {
|
|
4485
4553
|
if (!isRunning) {
|
|
4486
4554
|
setElapsed(0);
|
|
4487
4555
|
return;
|
|
@@ -4498,7 +4566,7 @@ function useElapsedSeconds(isRunning) {
|
|
|
4498
4566
|
|
|
4499
4567
|
// src/hooks/useTextMode.ts
|
|
4500
4568
|
import { useLocalParticipant as useLocalParticipant9 } from "@livekit/components-react/hooks";
|
|
4501
|
-
import { useCallback as useCallback12, useContext as useContext9, useRef as
|
|
4569
|
+
import { useCallback as useCallback12, useContext as useContext9, useRef as useRef13 } from "react";
|
|
4502
4570
|
var textEncoder5 = new TextEncoder;
|
|
4503
4571
|
function useTextMode() {
|
|
4504
4572
|
const ctx = useContext9(LiveAgentContext);
|
|
@@ -4507,7 +4575,7 @@ function useTextMode() {
|
|
|
4507
4575
|
}
|
|
4508
4576
|
const { textMode, setTextModeState, sidebarTab, setSidebarTab } = ctx;
|
|
4509
4577
|
const { localParticipant } = useLocalParticipant9();
|
|
4510
|
-
const confirmedTextModeRef =
|
|
4578
|
+
const confirmedTextModeRef = useRef13(false);
|
|
4511
4579
|
const toggleTextMode = useCallback12(async () => {
|
|
4512
4580
|
const next = !textMode;
|
|
4513
4581
|
setTextModeState(next);
|
|
@@ -4548,7 +4616,7 @@ function ChatHeader() {
|
|
|
4548
4616
|
setIsDragging
|
|
4549
4617
|
} = ctx;
|
|
4550
4618
|
const elapsed = useElapsedSeconds(isConnected);
|
|
4551
|
-
const headerRef =
|
|
4619
|
+
const headerRef = useRef14(null);
|
|
4552
4620
|
const followsPanel = variant === "floating" && isPanelOpen;
|
|
4553
4621
|
const dragFollowers = followsPanel ? [panelRef, controlBarRef] : null;
|
|
4554
4622
|
const { wasDraggedRef } = useLauncherDrag(headerRef, commitLauncherDrop, dragFollowers, setIsDragging);
|
|
@@ -4665,7 +4733,7 @@ function LoadingDots({ label }) {
|
|
|
4665
4733
|
}
|
|
4666
4734
|
|
|
4667
4735
|
// src/components/LoginFlow.tsx
|
|
4668
|
-
import { useCallback as useCallback13, useEffect as
|
|
4736
|
+
import { useCallback as useCallback13, useEffect as useEffect23, useRef as useRef15, useState as useState16 } from "react";
|
|
4669
4737
|
|
|
4670
4738
|
// src/components/ui/button.tsx
|
|
4671
4739
|
import { forwardRef as forwardRef3 } from "react";
|
|
@@ -4793,16 +4861,16 @@ function EmailStep({ email, onEmailChange, onSubmit, error, isSubmitting }) {
|
|
|
4793
4861
|
function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
|
|
4794
4862
|
const [digits, setDigits] = useState16(Array(OTP_LENGTH).fill(""));
|
|
4795
4863
|
const [resendCooldown, setResendCooldown] = useState16(0);
|
|
4796
|
-
const inputRefs =
|
|
4797
|
-
const submittedRef =
|
|
4798
|
-
|
|
4864
|
+
const inputRefs = useRef15([]);
|
|
4865
|
+
const submittedRef = useRef15(false);
|
|
4866
|
+
useEffect23(() => {
|
|
4799
4867
|
inputRefs.current[0]?.focus();
|
|
4800
4868
|
}, []);
|
|
4801
|
-
|
|
4869
|
+
useEffect23(() => {
|
|
4802
4870
|
if (error)
|
|
4803
4871
|
submittedRef.current = false;
|
|
4804
4872
|
}, [error]);
|
|
4805
|
-
|
|
4873
|
+
useEffect23(() => {
|
|
4806
4874
|
if (resendCooldown <= 0)
|
|
4807
4875
|
return;
|
|
4808
4876
|
const timer = setTimeout(() => setResendCooldown((c) => c - 1), 1000);
|
|
@@ -4943,17 +5011,17 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
|
|
|
4943
5011
|
}
|
|
4944
5012
|
|
|
4945
5013
|
// src/components/MessageList.tsx
|
|
4946
|
-
import { useCallback as useCallback14, useLayoutEffect as useLayoutEffect3, useRef as
|
|
5014
|
+
import { useCallback as useCallback14, useLayoutEffect as useLayoutEffect3, useRef as useRef17, useState as useState18 } from "react";
|
|
4947
5015
|
|
|
4948
5016
|
// src/components/ChatInput.tsx
|
|
4949
|
-
import { useEffect as
|
|
5017
|
+
import { useEffect as useEffect24, useRef as useRef16, useState as useState17 } from "react";
|
|
4950
5018
|
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4951
5019
|
var MAX_INPUT_HEIGHT = 60;
|
|
4952
5020
|
function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
|
|
4953
5021
|
const [inputText, setInputText] = useState17("");
|
|
4954
|
-
const textareaRef =
|
|
5022
|
+
const textareaRef = useRef16(null);
|
|
4955
5023
|
const canSend = inputText.trim().length > 0 && !isSendingChat;
|
|
4956
|
-
|
|
5024
|
+
useEffect24(() => {
|
|
4957
5025
|
if (autoFocus)
|
|
4958
5026
|
textareaRef.current?.focus();
|
|
4959
5027
|
}, [autoFocus]);
|
|
@@ -5044,7 +5112,7 @@ function ChatMessage({ message }) {
|
|
|
5044
5112
|
}
|
|
5045
5113
|
|
|
5046
5114
|
// src/components/PlanCard.tsx
|
|
5047
|
-
import { useEffect as
|
|
5115
|
+
import { useEffect as useEffect25 } from "react";
|
|
5048
5116
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5049
5117
|
var APPROVE_MESSAGE = "Yes, go ahead.";
|
|
5050
5118
|
var CANCEL_MESSAGE = "No, cancel that.";
|
|
@@ -5071,7 +5139,7 @@ function StepIcon({ status }) {
|
|
|
5071
5139
|
}
|
|
5072
5140
|
function PlanCard({ plan, sendChatMessage, onDismiss }) {
|
|
5073
5141
|
const awaitingApproval = plan.state === "proposed";
|
|
5074
|
-
|
|
5142
|
+
useEffect25(() => {
|
|
5075
5143
|
if (plan.state !== "completed")
|
|
5076
5144
|
return;
|
|
5077
5145
|
const timer = setTimeout(onDismiss, COMPLETED_CARD_VISIBLE_MS);
|
|
@@ -5164,9 +5232,9 @@ function MessageList({
|
|
|
5164
5232
|
autoFocus = false,
|
|
5165
5233
|
readOnly = false
|
|
5166
5234
|
}) {
|
|
5167
|
-
const containerRef =
|
|
5168
|
-
const isPinnedToBottom =
|
|
5169
|
-
const lastSeenMessageId =
|
|
5235
|
+
const containerRef = useRef17(null);
|
|
5236
|
+
const isPinnedToBottom = useRef17(true);
|
|
5237
|
+
const lastSeenMessageId = useRef17(undefined);
|
|
5170
5238
|
const [showJumpToLatest, setShowJumpToLatest] = useState18(false);
|
|
5171
5239
|
const lastMessage = messages.length > 0 ? messages[messages.length - 1] : undefined;
|
|
5172
5240
|
const [dismissedPlanId, setDismissedPlanId] = useState18(null);
|
|
@@ -5390,7 +5458,7 @@ function Sidebar({
|
|
|
5390
5458
|
height: panelExpanded ? availableHeight : `min(${PANEL_MAX_HEIGHT_PX}px, ${availableHeight})`
|
|
5391
5459
|
};
|
|
5392
5460
|
}
|
|
5393
|
-
|
|
5461
|
+
useEffect26(() => {
|
|
5394
5462
|
if (!isSidebar)
|
|
5395
5463
|
return;
|
|
5396
5464
|
const prop = position === "right" ? "marginRight" : "marginLeft";
|
|
@@ -5757,8 +5825,8 @@ function AgentCursorMount({ animated }) {
|
|
|
5757
5825
|
function PlanPanelOpener() {
|
|
5758
5826
|
const plan = usePlanUpdates();
|
|
5759
5827
|
const { expandPanel } = useLiveAgent();
|
|
5760
|
-
const surfacedPlanIdRef =
|
|
5761
|
-
|
|
5828
|
+
const surfacedPlanIdRef = useRef18(null);
|
|
5829
|
+
useEffect27(() => {
|
|
5762
5830
|
if (plan?.state !== "proposed" || surfacedPlanIdRef.current === plan.planId)
|
|
5763
5831
|
return;
|
|
5764
5832
|
surfacedPlanIdRef.current = plan.planId;
|
|
@@ -5844,7 +5912,7 @@ function LiveAgent(props) {
|
|
|
5844
5912
|
onStartError: expandOnSessionStartError,
|
|
5845
5913
|
onDisconnect: minimizeOnSessionDisconnect
|
|
5846
5914
|
});
|
|
5847
|
-
const teardownInFlightRef =
|
|
5915
|
+
const teardownInFlightRef = useRef18(false);
|
|
5848
5916
|
teardownInFlightRef.current = isPaused || isPausing || isDisconnecting;
|
|
5849
5917
|
const handleRoomDisconnected = useCallback15(() => {
|
|
5850
5918
|
if (teardownInFlightRef.current)
|
|
@@ -5859,15 +5927,15 @@ function LiveAgent(props) {
|
|
|
5859
5927
|
const [textMode, setTextMode] = useState19(false);
|
|
5860
5928
|
const [panelExpanded, setPanelExpanded] = useState19(false);
|
|
5861
5929
|
const togglePanelExpanded = useCallback15(() => setPanelExpanded((prev) => !prev), []);
|
|
5862
|
-
const panelRef =
|
|
5863
|
-
const controlBarRef =
|
|
5930
|
+
const panelRef = useRef18(null);
|
|
5931
|
+
const controlBarRef = useRef18(null);
|
|
5864
5932
|
const [isDragging, setIsDragging] = useState19(false);
|
|
5865
5933
|
const setTextModeState = useCallback15((enabled) => {
|
|
5866
5934
|
setTextMode(enabled);
|
|
5867
5935
|
}, []);
|
|
5868
5936
|
const isConnected = connection !== null;
|
|
5869
5937
|
const showControlBar = isConnected || isStarting || isPausing;
|
|
5870
|
-
|
|
5938
|
+
useEffect27(() => {
|
|
5871
5939
|
if (!isConnected)
|
|
5872
5940
|
setTextModeState(false);
|
|
5873
5941
|
}, [isConnected, setTextModeState]);
|
|
@@ -5894,7 +5962,7 @@ function LiveAgent(props) {
|
|
|
5894
5962
|
const agentControls = operatingModule?.controls ?? hostAgentControls;
|
|
5895
5963
|
const agentMode = operatingModule?.mode ?? null;
|
|
5896
5964
|
const shouldAnimateCursor = operatingModule?.uiPreferences?.animateCursor ?? animateAgentCursor;
|
|
5897
|
-
const resumableSession =
|
|
5965
|
+
const resumableSession = useMemo7(() => getResumableSession(operatingModule), [operatingModule]);
|
|
5898
5966
|
const resumeSession = useCallback15(async () => {
|
|
5899
5967
|
if (!resumableSession)
|
|
5900
5968
|
return;
|
|
@@ -5904,7 +5972,7 @@ function LiveAgent(props) {
|
|
|
5904
5972
|
existingSessionId: resumableSession.id
|
|
5905
5973
|
});
|
|
5906
5974
|
}, [resumableSession, startSession, agentControls]);
|
|
5907
|
-
const selectModule = useCallback15((moduleId) => {
|
|
5975
|
+
const selectModule = useCallback15((moduleId, opts) => {
|
|
5908
5976
|
const found = availableModules.find((m) => m.id === moduleId);
|
|
5909
5977
|
if (!found)
|
|
5910
5978
|
return;
|
|
@@ -5912,7 +5980,8 @@ function LiveAgent(props) {
|
|
|
5912
5980
|
startSession({
|
|
5913
5981
|
agentId: found.id,
|
|
5914
5982
|
agentControls: found.controls,
|
|
5915
|
-
existingSessionId: getResumableSessionId(found.currentSession, found.mode)
|
|
5983
|
+
existingSessionId: getResumableSessionId(found.currentSession, found.mode),
|
|
5984
|
+
autoStarted: opts?.autoStarted
|
|
5916
5985
|
});
|
|
5917
5986
|
}, [availableModules, startSession]);
|
|
5918
5987
|
const startAdoptionSession = useCallback15((goal) => {
|
|
@@ -5943,8 +6012,8 @@ function LiveAgent(props) {
|
|
|
5943
6012
|
} catch {}
|
|
5944
6013
|
}, []);
|
|
5945
6014
|
const savedLauncherBottom = readSavedLauncherBottom();
|
|
5946
|
-
const hasDraggedRef =
|
|
5947
|
-
const verticalAlignRef =
|
|
6015
|
+
const hasDraggedRef = useRef18(savedLauncherBottom !== null);
|
|
6016
|
+
const verticalAlignRef = useRef18(verticalAlign);
|
|
5948
6017
|
const [launcherBottomPx, setLauncherBottomPxState] = useState19(() => savedLauncherBottom !== null ? clampLauncherBottom(savedLauncherBottom) : verticalAlignToBottomPx(verticalAlign));
|
|
5949
6018
|
const [popsDown, setPopsDown] = useState19(() => launcherPopsDown(launcherBottomPx));
|
|
5950
6019
|
const setLauncherBottomPx = useCallback15((px) => {
|
|
@@ -5955,13 +6024,13 @@ function LiveAgent(props) {
|
|
|
5955
6024
|
localStorage.setItem("skippr_widget_bottom", String(px));
|
|
5956
6025
|
} catch {}
|
|
5957
6026
|
}, []);
|
|
5958
|
-
const launcherBottomPxRef =
|
|
6027
|
+
const launcherBottomPxRef = useRef18(launcherBottomPx);
|
|
5959
6028
|
launcherBottomPxRef.current = launcherBottomPx;
|
|
5960
6029
|
const commitLauncherDrop = useCallback15(({ side, bottomPx }) => {
|
|
5961
6030
|
setPositionWithPersist(side);
|
|
5962
6031
|
setLauncherBottomPx(bottomPx);
|
|
5963
6032
|
}, [setPositionWithPersist, setLauncherBottomPx]);
|
|
5964
|
-
|
|
6033
|
+
useEffect27(() => {
|
|
5965
6034
|
const syncToViewport = () => {
|
|
5966
6035
|
const next = hasDraggedRef.current ? clampLauncherBottom(launcherBottomPxRef.current) : verticalAlignToBottomPx(verticalAlignRef.current);
|
|
5967
6036
|
setLauncherBottomPxState(next);
|
|
@@ -5994,12 +6063,14 @@ function LiveAgent(props) {
|
|
|
5994
6063
|
const target = availableModules.find((m) => m.id === defaultAgentId);
|
|
5995
6064
|
if (!target)
|
|
5996
6065
|
return;
|
|
6066
|
+
setActiveModule(target);
|
|
5997
6067
|
startSession({
|
|
5998
6068
|
agentId: target.id,
|
|
5999
6069
|
agentControls: target.controls,
|
|
6000
6070
|
existingSessionId: defaultSelection.sessionId ?? undefined
|
|
6001
6071
|
});
|
|
6002
6072
|
}, [defaultAgentId, availableModules, defaultSelection.sessionId, startSession]);
|
|
6073
|
+
useAutoStart({ availableModules, isSessionLive, bearerToken, selectModule });
|
|
6003
6074
|
const idleHistoryEnabled = !isSessionLive && !isPaused && isPanelOpen && isAuthenticated;
|
|
6004
6075
|
const {
|
|
6005
6076
|
messages: idleHistoryMessages,
|
|
@@ -6010,12 +6081,12 @@ function LiveAgent(props) {
|
|
|
6010
6081
|
enabled: idleHistoryEnabled,
|
|
6011
6082
|
authedFetch
|
|
6012
6083
|
});
|
|
6013
|
-
const idleHistory =
|
|
6084
|
+
const idleHistory = useMemo7(() => ({
|
|
6014
6085
|
messages: idleHistoryMessages,
|
|
6015
6086
|
phases: idleHistoryPhases,
|
|
6016
6087
|
isLoading: isLoadingHistory
|
|
6017
6088
|
}), [idleHistoryMessages, idleHistoryPhases, isLoadingHistory]);
|
|
6018
|
-
const ctx =
|
|
6089
|
+
const ctx = useMemo7(() => ({
|
|
6019
6090
|
connection,
|
|
6020
6091
|
shouldConnect,
|
|
6021
6092
|
isConnected,
|