@skippr/live-agent-sdk 0.74.0 → 0.76.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 +993 -744
- package/dist/skippr-sdk.css +1 -1
- package/dist/skippr-sdk.js +108 -108
- package/dist/types/components/MessageList.d.ts +4 -3
- package/dist/types/components/ModulePill.d.ts +1 -7
- package/dist/types/context/LiveAgentContext.d.ts +14 -0
- package/dist/types/context/SessionHoldContext.d.ts +8 -0
- package/dist/types/hooks/useAutoStart.d.ts +11 -0
- package/dist/types/hooks/useAvailableModules.d.ts +4 -2
- package/dist/types/hooks/useSession.d.ts +2 -1
- package/dist/types/hooks/useSessionHistory.d.ts +15 -0
- package/dist/types/lib/session.d.ts +8 -0
- package/package.json +1 -1
- package/dist/types/components/StartSessionPrompt.d.ts +0 -16
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";
|
|
@@ -74,8 +74,128 @@ var NAME_MAX_CHARS = 80;
|
|
|
74
74
|
// src/context/LiveAgentContext.tsx
|
|
75
75
|
var LiveAgentContext = createContext(null);
|
|
76
76
|
|
|
77
|
+
// src/context/SessionHoldContext.tsx
|
|
78
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
79
|
+
|
|
80
|
+
// src/hooks/useLiveAgent.ts
|
|
81
|
+
import { useContext } from "react";
|
|
82
|
+
function useLiveAgent() {
|
|
83
|
+
const ctx = useContext(LiveAgentContext);
|
|
84
|
+
if (!ctx) {
|
|
85
|
+
throw new Error("useLiveAgent must be used within a <LiveAgent> provider");
|
|
86
|
+
}
|
|
87
|
+
const {
|
|
88
|
+
usesHostAuth,
|
|
89
|
+
authFailed,
|
|
90
|
+
connection,
|
|
91
|
+
shouldConnect,
|
|
92
|
+
historyMessages,
|
|
93
|
+
phasesSnapshot,
|
|
94
|
+
setPhasesSnapshot,
|
|
95
|
+
hasResolvedModules,
|
|
96
|
+
adoptionGoals,
|
|
97
|
+
startAdoptionSession,
|
|
98
|
+
launcherBottomPx,
|
|
99
|
+
setLauncherBottomPx,
|
|
100
|
+
popsDown,
|
|
101
|
+
panelExpanded,
|
|
102
|
+
togglePanelExpanded,
|
|
103
|
+
...publicValue
|
|
104
|
+
} = ctx;
|
|
105
|
+
return publicValue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/hooks/useSessionHold.ts
|
|
109
|
+
import { useLocalParticipant } from "@livekit/components-react/hooks";
|
|
110
|
+
import { useCallback, useEffect as useEffect2, useState as useState2 } from "react";
|
|
111
|
+
var textEncoder = new TextEncoder;
|
|
112
|
+
var FALLBACK_PAUSE_TIMEOUT_SECONDS = 120;
|
|
113
|
+
function useSessionHold({
|
|
114
|
+
pauseSession,
|
|
115
|
+
pauseTimeoutSeconds
|
|
116
|
+
}) {
|
|
117
|
+
const { localParticipant } = useLocalParticipant();
|
|
118
|
+
const timeoutSeconds = pauseTimeoutSeconds ?? FALLBACK_PAUSE_TIMEOUT_SECONDS;
|
|
119
|
+
const [isHeld, setIsHeld] = useState2(false);
|
|
120
|
+
const [countdown, setCountdown] = useState2(timeoutSeconds);
|
|
121
|
+
const publish = useCallback(async (type) => {
|
|
122
|
+
await localParticipant.publishData(textEncoder.encode(JSON.stringify({ type })), {
|
|
123
|
+
reliable: true,
|
|
124
|
+
topic: SESSION_HOLD_TOPIC
|
|
125
|
+
});
|
|
126
|
+
}, [localParticipant]);
|
|
127
|
+
const hold = useCallback(async () => {
|
|
128
|
+
try {
|
|
129
|
+
await localParticipant.setMicrophoneEnabled(false);
|
|
130
|
+
await publish("pause");
|
|
131
|
+
setIsHeld(true);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error("Failed to hold session:", error);
|
|
134
|
+
}
|
|
135
|
+
}, [localParticipant, publish]);
|
|
136
|
+
const release = useCallback(async () => {
|
|
137
|
+
try {
|
|
138
|
+
await localParticipant.setMicrophoneEnabled(true);
|
|
139
|
+
await publish("resume");
|
|
140
|
+
setIsHeld(false);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error("Failed to release session:", error);
|
|
143
|
+
}
|
|
144
|
+
}, [localParticipant, publish]);
|
|
145
|
+
useEffect2(() => {
|
|
146
|
+
if (!isHeld) {
|
|
147
|
+
setCountdown(timeoutSeconds);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const id = setInterval(() => {
|
|
151
|
+
setCountdown((seconds) => Math.max(0, seconds - 1));
|
|
152
|
+
}, 1000);
|
|
153
|
+
return () => clearInterval(id);
|
|
154
|
+
}, [isHeld, timeoutSeconds]);
|
|
155
|
+
useEffect2(() => {
|
|
156
|
+
if (isHeld && countdown === 0) {
|
|
157
|
+
setIsHeld(false);
|
|
158
|
+
pauseSession();
|
|
159
|
+
}
|
|
160
|
+
}, [isHeld, countdown, pauseSession]);
|
|
161
|
+
const toggle = useCallback(() => {
|
|
162
|
+
if (isHeld) {
|
|
163
|
+
release();
|
|
164
|
+
} else {
|
|
165
|
+
hold();
|
|
166
|
+
}
|
|
167
|
+
}, [isHeld, hold, release]);
|
|
168
|
+
return { isHeld, countdown, toggle };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// src/context/SessionHoldContext.tsx
|
|
172
|
+
import { jsx } from "react/jsx-runtime";
|
|
173
|
+
var SessionHoldContext = createContext2({
|
|
174
|
+
isHeld: false,
|
|
175
|
+
countdown: 0,
|
|
176
|
+
toggle: () => {}
|
|
177
|
+
});
|
|
178
|
+
function SessionHoldProvider({ children }) {
|
|
179
|
+
const { pauseSession } = useLiveAgent();
|
|
180
|
+
const internalCtx = useContext2(LiveAgentContext);
|
|
181
|
+
if (!internalCtx) {
|
|
182
|
+
throw new Error("SessionHoldProvider must be used within a <LiveAgent> provider");
|
|
183
|
+
}
|
|
184
|
+
const hold = useSessionHold({
|
|
185
|
+
pauseSession,
|
|
186
|
+
pauseTimeoutSeconds: internalCtx.pauseTimeoutSeconds
|
|
187
|
+
});
|
|
188
|
+
return /* @__PURE__ */ jsx(SessionHoldContext.Provider, {
|
|
189
|
+
value: hold,
|
|
190
|
+
children
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
function useSessionHoldContext() {
|
|
194
|
+
return useContext2(SessionHoldContext);
|
|
195
|
+
}
|
|
196
|
+
|
|
77
197
|
// src/hooks/useAdoptionGoals.ts
|
|
78
|
-
import { useCallback, useEffect as
|
|
198
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useMemo, useState as useState3 } from "react";
|
|
79
199
|
|
|
80
200
|
// src/lib/hashMatch.ts
|
|
81
201
|
function globToRegExp(pattern) {
|
|
@@ -143,9 +263,9 @@ function useAdoptionGoals({
|
|
|
143
263
|
bearerToken,
|
|
144
264
|
authedFetch
|
|
145
265
|
}) {
|
|
146
|
-
const [candidates, setCandidates] =
|
|
147
|
-
const [hash, setHash] =
|
|
148
|
-
const match =
|
|
266
|
+
const [candidates, setCandidates] = useState3([]);
|
|
267
|
+
const [hash, setHash] = useState3(window.location.hash);
|
|
268
|
+
const match = useCallback2(async () => {
|
|
149
269
|
try {
|
|
150
270
|
const resp = await authedFetch(`${API_URL}/v1/adoption/goals/match`, {
|
|
151
271
|
method: "POST",
|
|
@@ -163,7 +283,7 @@ function useAdoptionGoals({
|
|
|
163
283
|
setCandidates([]);
|
|
164
284
|
}
|
|
165
285
|
}, [authedFetch]);
|
|
166
|
-
|
|
286
|
+
useEffect3(() => {
|
|
167
287
|
if (!enabled || !bearerToken) {
|
|
168
288
|
setCandidates([]);
|
|
169
289
|
return;
|
|
@@ -195,21 +315,21 @@ function useAdoptionGoals({
|
|
|
195
315
|
return hashSpecific;
|
|
196
316
|
return candidates.filter((goal) => goal.hashPattern === null);
|
|
197
317
|
}, [candidates, hash]);
|
|
198
|
-
const postStatus =
|
|
318
|
+
const postStatus = useCallback2((goalId, status) => {
|
|
199
319
|
authedFetch(`${API_URL}/v1/adoption/goals/${goalId}/status`, {
|
|
200
320
|
method: "POST",
|
|
201
321
|
headers: { "Content-Type": "application/json" },
|
|
202
322
|
body: JSON.stringify({ status })
|
|
203
323
|
}).catch((e) => console.warn("[Skippr] adoption status update failed", e));
|
|
204
324
|
}, [authedFetch]);
|
|
205
|
-
const attendGoal =
|
|
325
|
+
const attendGoal = useCallback2((goalId) => {
|
|
206
326
|
postStatus(goalId, "attended" /* Attended */);
|
|
207
327
|
}, [postStatus]);
|
|
208
328
|
return { goals, attendGoal };
|
|
209
329
|
}
|
|
210
330
|
|
|
211
331
|
// src/hooks/useAuth.ts
|
|
212
|
-
import { useCallback as
|
|
332
|
+
import { useCallback as useCallback3, useEffect as useEffect4, useState as useState4 } from "react";
|
|
213
333
|
var API_URL2 = "https://specialist.skippr.ai/api";
|
|
214
334
|
function storageKey(appKey) {
|
|
215
335
|
return `skippr_auth_${appKey}`;
|
|
@@ -236,12 +356,12 @@ function clearStoredToken(appKey) {
|
|
|
236
356
|
}
|
|
237
357
|
}
|
|
238
358
|
function useAuth({ appKey }) {
|
|
239
|
-
const [authToken, setAuthToken] =
|
|
240
|
-
const [isValidating, setIsValidating] =
|
|
241
|
-
const [isSubmitting, setIsSubmitting] =
|
|
242
|
-
const [error, setError] =
|
|
359
|
+
const [authToken, setAuthToken] = useState4(null);
|
|
360
|
+
const [isValidating, setIsValidating] = useState4(false);
|
|
361
|
+
const [isSubmitting, setIsSubmitting] = useState4(false);
|
|
362
|
+
const [error, setError] = useState4("");
|
|
243
363
|
const isAuthenticated = authToken !== null;
|
|
244
|
-
|
|
364
|
+
useEffect4(() => {
|
|
245
365
|
if (!appKey)
|
|
246
366
|
return;
|
|
247
367
|
const stored = getStoredToken(appKey);
|
|
@@ -267,7 +387,7 @@ function useAuth({ appKey }) {
|
|
|
267
387
|
}
|
|
268
388
|
validateStoredToken();
|
|
269
389
|
}, [appKey]);
|
|
270
|
-
|
|
390
|
+
useEffect4(() => {
|
|
271
391
|
function handleLogout() {
|
|
272
392
|
setAuthToken(null);
|
|
273
393
|
setError("");
|
|
@@ -275,7 +395,7 @@ function useAuth({ appKey }) {
|
|
|
275
395
|
window.addEventListener("skippr:logout", handleLogout);
|
|
276
396
|
return () => window.removeEventListener("skippr:logout", handleLogout);
|
|
277
397
|
}, []);
|
|
278
|
-
const requestOtp =
|
|
398
|
+
const requestOtp = useCallback3(async (email) => {
|
|
279
399
|
if (!appKey)
|
|
280
400
|
return false;
|
|
281
401
|
setIsSubmitting(true);
|
|
@@ -302,7 +422,7 @@ function useAuth({ appKey }) {
|
|
|
302
422
|
setIsSubmitting(false);
|
|
303
423
|
}
|
|
304
424
|
}, [appKey]);
|
|
305
|
-
const verifyOtp =
|
|
425
|
+
const verifyOtp = useCallback3(async (email, code) => {
|
|
306
426
|
if (!appKey)
|
|
307
427
|
return;
|
|
308
428
|
setIsSubmitting(true);
|
|
@@ -331,7 +451,7 @@ function useAuth({ appKey }) {
|
|
|
331
451
|
setIsSubmitting(false);
|
|
332
452
|
}
|
|
333
453
|
}, [appKey]);
|
|
334
|
-
const logout =
|
|
454
|
+
const logout = useCallback3(async () => {
|
|
335
455
|
const token = authToken;
|
|
336
456
|
if (appKey)
|
|
337
457
|
clearStoredToken(appKey);
|
|
@@ -361,44 +481,169 @@ function useAuth({ appKey }) {
|
|
|
361
481
|
};
|
|
362
482
|
}
|
|
363
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
|
+
|
|
364
603
|
// src/hooks/useAvailableModules.ts
|
|
365
|
-
import { useCallback as
|
|
604
|
+
import { useCallback as useCallback4, useEffect as useEffect6, useState as useState5 } from "react";
|
|
605
|
+
var EMPTY_DEFAULT = { agentId: null, sessionId: null };
|
|
366
606
|
var API_URL3 = "https://specialist.skippr.ai/api";
|
|
367
607
|
function useAvailableModules({
|
|
368
608
|
enabled,
|
|
369
609
|
bearerToken,
|
|
370
|
-
authedFetch
|
|
610
|
+
authedFetch,
|
|
611
|
+
agentId
|
|
371
612
|
}) {
|
|
372
|
-
const [modules, setModules] =
|
|
373
|
-
const [
|
|
374
|
-
const [
|
|
375
|
-
const [
|
|
376
|
-
const
|
|
613
|
+
const [modules, setModules] = useState5([]);
|
|
614
|
+
const [defaultSelection, setDefaultSelection] = useState5(EMPTY_DEFAULT);
|
|
615
|
+
const [isLoading, setIsLoading] = useState5(false);
|
|
616
|
+
const [hasResolved, setHasResolved] = useState5(false);
|
|
617
|
+
const [error, setError] = useState5(null);
|
|
618
|
+
const fetchModules = useCallback4(async () => {
|
|
377
619
|
setIsLoading(true);
|
|
378
620
|
setHasResolved(false);
|
|
379
621
|
setError(null);
|
|
380
622
|
try {
|
|
381
|
-
const
|
|
623
|
+
const query = agentId ? `?agentId=${encodeURIComponent(agentId)}` : "";
|
|
624
|
+
const resp = await authedFetch(`${API_URL3}/v1/modules/available${query}`);
|
|
382
625
|
if (!resp.ok) {
|
|
383
626
|
const body = await resp.json().catch(() => null);
|
|
384
627
|
throw new Error(body?.detail || `Failed to load modules: ${resp.status}`);
|
|
385
628
|
}
|
|
386
629
|
const data = await resp.json();
|
|
387
630
|
setModules(Array.isArray(data?.modules) ? data.modules : []);
|
|
631
|
+
setDefaultSelection(data?.default ?? EMPTY_DEFAULT);
|
|
388
632
|
} catch (e) {
|
|
389
633
|
setError(e instanceof Error ? e.message : "Failed to load modules");
|
|
390
634
|
} finally {
|
|
391
635
|
setIsLoading(false);
|
|
392
636
|
setHasResolved(true);
|
|
393
637
|
}
|
|
394
|
-
}, [authedFetch]);
|
|
395
|
-
|
|
638
|
+
}, [authedFetch, agentId]);
|
|
639
|
+
useEffect6(() => {
|
|
396
640
|
if (!enabled || !bearerToken)
|
|
397
641
|
return;
|
|
398
642
|
fetchModules();
|
|
399
643
|
}, [enabled, bearerToken, fetchModules]);
|
|
400
644
|
return {
|
|
401
645
|
modules,
|
|
646
|
+
defaultSelection,
|
|
402
647
|
isLoading,
|
|
403
648
|
hasResolved,
|
|
404
649
|
error,
|
|
@@ -406,44 +651,16 @@ function useAvailableModules({
|
|
|
406
651
|
};
|
|
407
652
|
}
|
|
408
653
|
|
|
409
|
-
// src/hooks/useLiveAgent.ts
|
|
410
|
-
import { useContext } from "react";
|
|
411
|
-
function useLiveAgent() {
|
|
412
|
-
const ctx = useContext(LiveAgentContext);
|
|
413
|
-
if (!ctx) {
|
|
414
|
-
throw new Error("useLiveAgent must be used within a <LiveAgent> provider");
|
|
415
|
-
}
|
|
416
|
-
const {
|
|
417
|
-
usesHostAuth,
|
|
418
|
-
authFailed,
|
|
419
|
-
connection,
|
|
420
|
-
shouldConnect,
|
|
421
|
-
historyMessages,
|
|
422
|
-
phasesSnapshot,
|
|
423
|
-
setPhasesSnapshot,
|
|
424
|
-
hasResolvedModules,
|
|
425
|
-
adoptionGoals,
|
|
426
|
-
startAdoptionSession,
|
|
427
|
-
launcherBottomPx,
|
|
428
|
-
setLauncherBottomPx,
|
|
429
|
-
popsDown,
|
|
430
|
-
panelExpanded,
|
|
431
|
-
togglePanelExpanded,
|
|
432
|
-
...publicValue
|
|
433
|
-
} = ctx;
|
|
434
|
-
return publicValue;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
654
|
// src/hooks/usePlanUpdates.ts
|
|
438
|
-
import { useCallback as
|
|
655
|
+
import { useCallback as useCallback5 } from "react";
|
|
439
656
|
|
|
440
657
|
// src/hooks/useAgentState.ts
|
|
441
658
|
import { useRemoteParticipants } from "@livekit/components-react/hooks";
|
|
442
|
-
import { useEffect as
|
|
659
|
+
import { useEffect as useEffect7, useState as useState6 } from "react";
|
|
443
660
|
function useAgentState(attributeKey, parse, initial) {
|
|
444
|
-
const [value, setValue] =
|
|
661
|
+
const [value, setValue] = useState6(initial);
|
|
445
662
|
const remoteParticipants = useRemoteParticipants();
|
|
446
|
-
|
|
663
|
+
useEffect7(() => {
|
|
447
664
|
const agentParticipant = remoteParticipants.find((p) => p.attributes?.[attributeKey]);
|
|
448
665
|
if (agentParticipant) {
|
|
449
666
|
const attr = agentParticipant.attributes?.[attributeKey];
|
|
@@ -489,12 +706,12 @@ function parsePlan(json) {
|
|
|
489
706
|
return null;
|
|
490
707
|
}
|
|
491
708
|
function usePlanUpdates() {
|
|
492
|
-
const parse =
|
|
709
|
+
const parse = useCallback5(parsePlan, []);
|
|
493
710
|
return useAgentState(PLAN_ATTR, parse, null);
|
|
494
711
|
}
|
|
495
712
|
|
|
496
713
|
// src/hooks/useSession.ts
|
|
497
|
-
import { useCallback as
|
|
714
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useRef as useRef2, useState as useState7 } from "react";
|
|
498
715
|
var API_URL4 = "https://specialist.skippr.ai/api";
|
|
499
716
|
async function fetchSessionMessages(sessionId, authedFetch) {
|
|
500
717
|
try {
|
|
@@ -502,13 +719,7 @@ async function fetchSessionMessages(sessionId, authedFetch) {
|
|
|
502
719
|
if (!resp.ok)
|
|
503
720
|
return [];
|
|
504
721
|
const { messages } = await resp.json();
|
|
505
|
-
return messages
|
|
506
|
-
id: message.id,
|
|
507
|
-
role: message.role === "user" ? "user" : "assistant",
|
|
508
|
-
content: message.content,
|
|
509
|
-
source: "chat",
|
|
510
|
-
timestamp: new Date(message.createdAt).getTime()
|
|
511
|
-
}));
|
|
722
|
+
return mapApiMessages(messages);
|
|
512
723
|
} catch {
|
|
513
724
|
return [];
|
|
514
725
|
}
|
|
@@ -552,27 +763,27 @@ function useSession({
|
|
|
552
763
|
onStartError,
|
|
553
764
|
onDisconnect
|
|
554
765
|
}) {
|
|
555
|
-
const [connection, setConnection] =
|
|
556
|
-
const [shouldConnect, setShouldConnect] =
|
|
557
|
-
const [isStarting, setIsStarting] =
|
|
558
|
-
const [isDisconnecting, setIsDisconnecting] =
|
|
559
|
-
const [error, setError] =
|
|
560
|
-
const [errorCode, setErrorCode] =
|
|
561
|
-
const [sessionId, setSessionId] =
|
|
562
|
-
const [bearerToken, setBearerToken] =
|
|
563
|
-
const [pendingScreenStream, setPendingScreenStream] =
|
|
564
|
-
const [isPaused, setIsPaused] =
|
|
565
|
-
const [isPausing, setIsPausing] =
|
|
566
|
-
const [pauseTimeoutSeconds, setPauseTimeoutSeconds] =
|
|
567
|
-
const [historyMessages, setHistoryMessages] =
|
|
568
|
-
const [authFailed, setAuthFailed] =
|
|
569
|
-
const tokenRef =
|
|
570
|
-
const getUserTokenRef =
|
|
766
|
+
const [connection, setConnection] = useState7(null);
|
|
767
|
+
const [shouldConnect, setShouldConnect] = useState7(false);
|
|
768
|
+
const [isStarting, setIsStarting] = useState7(false);
|
|
769
|
+
const [isDisconnecting, setIsDisconnecting] = useState7(false);
|
|
770
|
+
const [error, setError] = useState7("");
|
|
771
|
+
const [errorCode, setErrorCode] = useState7(null);
|
|
772
|
+
const [sessionId, setSessionId] = useState7(null);
|
|
773
|
+
const [bearerToken, setBearerToken] = useState7(authToken ?? null);
|
|
774
|
+
const [pendingScreenStream, setPendingScreenStream] = useState7(null);
|
|
775
|
+
const [isPaused, setIsPaused] = useState7(false);
|
|
776
|
+
const [isPausing, setIsPausing] = useState7(false);
|
|
777
|
+
const [pauseTimeoutSeconds, setPauseTimeoutSeconds] = useState7(null);
|
|
778
|
+
const [historyMessages, setHistoryMessages] = useState7([]);
|
|
779
|
+
const [authFailed, setAuthFailed] = useState7(false);
|
|
780
|
+
const tokenRef = useRef2(authToken ? { token: authToken, expiresAt: null } : null);
|
|
781
|
+
const getUserTokenRef = useRef2(getUserToken);
|
|
571
782
|
getUserTokenRef.current = getUserToken ?? (userToken ? () => Promise.resolve(userToken) : undefined);
|
|
572
|
-
const failedBearerRef =
|
|
573
|
-
const inFlightExchangeRef =
|
|
574
|
-
const canExchange =
|
|
575
|
-
const reExchange =
|
|
783
|
+
const failedBearerRef = useRef2(null);
|
|
784
|
+
const inFlightExchangeRef = useRef2(null);
|
|
785
|
+
const canExchange = useCallback6(() => !!appKey && !!getUserTokenRef.current, [appKey]);
|
|
786
|
+
const reExchange = useCallback6(async () => {
|
|
576
787
|
if (inFlightExchangeRef.current)
|
|
577
788
|
return inFlightExchangeRef.current;
|
|
578
789
|
const provider = getUserTokenRef.current;
|
|
@@ -592,7 +803,7 @@ function useSession({
|
|
|
592
803
|
inFlightExchangeRef.current = null;
|
|
593
804
|
}
|
|
594
805
|
}, [appKey]);
|
|
595
|
-
const getValidBearer =
|
|
806
|
+
const getValidBearer = useCallback6(async () => {
|
|
596
807
|
const current = tokenRef.current;
|
|
597
808
|
if (current) {
|
|
598
809
|
if (current.expiresAt === null)
|
|
@@ -604,7 +815,7 @@ function useSession({
|
|
|
604
815
|
return reExchange();
|
|
605
816
|
return current?.token ?? null;
|
|
606
817
|
}, [canExchange, reExchange]);
|
|
607
|
-
const authedFetch =
|
|
818
|
+
const authedFetch = useCallback6(async (input, init = {}) => {
|
|
608
819
|
const isSecretMode = canExchange();
|
|
609
820
|
const onTerminalAuthFailure = () => {
|
|
610
821
|
if (isSecretMode)
|
|
@@ -646,7 +857,7 @@ function useSession({
|
|
|
646
857
|
setAuthFailed(false);
|
|
647
858
|
return resp;
|
|
648
859
|
}, [canExchange, getValidBearer, reExchange]);
|
|
649
|
-
|
|
860
|
+
useEffect8(() => {
|
|
650
861
|
let stale = false;
|
|
651
862
|
if (authToken) {
|
|
652
863
|
tokenRef.current = { token: authToken, expiresAt: null };
|
|
@@ -665,9 +876,10 @@ function useSession({
|
|
|
665
876
|
stale = true;
|
|
666
877
|
};
|
|
667
878
|
}, [authToken, canExchange, reExchange]);
|
|
668
|
-
const
|
|
879
|
+
const isStartingRef = useRef2(false);
|
|
880
|
+
const pauseOnUnloadRef = useRef2(null);
|
|
669
881
|
pauseOnUnloadRef.current = connection !== null && !isPaused && sessionId && bearerToken ? { sessionId, bearerToken } : null;
|
|
670
|
-
|
|
882
|
+
useEffect8(() => {
|
|
671
883
|
const onPageHide = () => {
|
|
672
884
|
const pending = pauseOnUnloadRef.current;
|
|
673
885
|
if (!pending)
|
|
@@ -682,7 +894,15 @@ function useSession({
|
|
|
682
894
|
window.addEventListener("pagehide", onPageHide);
|
|
683
895
|
return () => window.removeEventListener("pagehide", onPageHide);
|
|
684
896
|
}, []);
|
|
685
|
-
const startSession =
|
|
897
|
+
const startSession = useCallback6(async ({
|
|
898
|
+
agentId,
|
|
899
|
+
agentControls,
|
|
900
|
+
existingSessionId,
|
|
901
|
+
adoptionGoalId,
|
|
902
|
+
autoStarted
|
|
903
|
+
}) => {
|
|
904
|
+
if (isStartingRef.current)
|
|
905
|
+
return;
|
|
686
906
|
if (!bearerToken) {
|
|
687
907
|
setError("No auth token available");
|
|
688
908
|
return;
|
|
@@ -691,6 +911,7 @@ function useSession({
|
|
|
691
911
|
setError("No agent selected");
|
|
692
912
|
return;
|
|
693
913
|
}
|
|
914
|
+
isStartingRef.current = true;
|
|
694
915
|
setIsStarting(true);
|
|
695
916
|
setError("");
|
|
696
917
|
setErrorCode(null);
|
|
@@ -731,7 +952,8 @@ function useSession({
|
|
|
731
952
|
body: JSON.stringify({
|
|
732
953
|
captureMode,
|
|
733
954
|
agentControls: requestAgentControls,
|
|
734
|
-
adoptionGoalId
|
|
955
|
+
adoptionGoalId,
|
|
956
|
+
autoStarted
|
|
735
957
|
})
|
|
736
958
|
});
|
|
737
959
|
if (!startResp.ok) {
|
|
@@ -760,10 +982,11 @@ function useSession({
|
|
|
760
982
|
setError(e instanceof Error ? e.message : "Failed to start session");
|
|
761
983
|
onStartError?.();
|
|
762
984
|
} finally {
|
|
985
|
+
isStartingRef.current = false;
|
|
763
986
|
setIsStarting(false);
|
|
764
987
|
}
|
|
765
988
|
}, [captureMode, bearerToken, authedFetch, onStart, onStartError]);
|
|
766
|
-
const pauseSession =
|
|
989
|
+
const pauseSession = useCallback6(async () => {
|
|
767
990
|
if (!sessionId || !bearerToken)
|
|
768
991
|
return;
|
|
769
992
|
setIsPausing(true);
|
|
@@ -789,7 +1012,7 @@ function useSession({
|
|
|
789
1012
|
setIsPaused(true);
|
|
790
1013
|
setIsPausing(false);
|
|
791
1014
|
}, [sessionId, bearerToken, authedFetch, pendingScreenStream]);
|
|
792
|
-
const disconnect =
|
|
1015
|
+
const disconnect = useCallback6(async () => {
|
|
793
1016
|
setIsDisconnecting(true);
|
|
794
1017
|
try {
|
|
795
1018
|
if (sessionId && bearerToken) {
|
|
@@ -833,6 +1056,55 @@ function useSession({
|
|
|
833
1056
|
};
|
|
834
1057
|
}
|
|
835
1058
|
|
|
1059
|
+
// src/hooks/useSessionHistory.ts
|
|
1060
|
+
import { useEffect as useEffect9, useState as useState8 } from "react";
|
|
1061
|
+
var API_URL5 = "https://specialist.skippr.ai/api";
|
|
1062
|
+
var EMPTY = { messages: [], phases: [] };
|
|
1063
|
+
function useSessionHistory({
|
|
1064
|
+
agentId,
|
|
1065
|
+
enabled,
|
|
1066
|
+
authedFetch
|
|
1067
|
+
}) {
|
|
1068
|
+
const [history2, setHistory] = useState8(EMPTY);
|
|
1069
|
+
const [loadedAgentId, setLoadedAgentId] = useState8(null);
|
|
1070
|
+
const activeAgentId = enabled && agentId ? agentId : null;
|
|
1071
|
+
const isLoading = activeAgentId !== null && activeAgentId !== loadedAgentId;
|
|
1072
|
+
useEffect9(() => {
|
|
1073
|
+
if (!enabled || !agentId) {
|
|
1074
|
+
setHistory(EMPTY);
|
|
1075
|
+
setLoadedAgentId(null);
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
let stale = false;
|
|
1079
|
+
(async () => {
|
|
1080
|
+
try {
|
|
1081
|
+
const resp = await authedFetch(`${API_URL5}/v1/modules/${agentId}/history`);
|
|
1082
|
+
if (!resp.ok)
|
|
1083
|
+
throw new Error(`Failed to load agent history: ${resp.status}`);
|
|
1084
|
+
const data = await resp.json();
|
|
1085
|
+
if (stale)
|
|
1086
|
+
return;
|
|
1087
|
+
setHistory({
|
|
1088
|
+
messages: mapApiMessages(data.messages),
|
|
1089
|
+
phases: data.phases
|
|
1090
|
+
});
|
|
1091
|
+
} catch (e) {
|
|
1092
|
+
if (stale)
|
|
1093
|
+
return;
|
|
1094
|
+
console.warn("[Skippr] Failed to load session history:", e);
|
|
1095
|
+
setHistory(EMPTY);
|
|
1096
|
+
} finally {
|
|
1097
|
+
if (!stale)
|
|
1098
|
+
setLoadedAgentId(agentId);
|
|
1099
|
+
}
|
|
1100
|
+
})();
|
|
1101
|
+
return () => {
|
|
1102
|
+
stale = true;
|
|
1103
|
+
};
|
|
1104
|
+
}, [enabled, agentId, authedFetch]);
|
|
1105
|
+
return { ...history2, isLoading };
|
|
1106
|
+
}
|
|
1107
|
+
|
|
836
1108
|
// src/lib/launcher.ts
|
|
837
1109
|
var DEFAULT_LAUNCHER_BOTTOM_PX = 48;
|
|
838
1110
|
var LAUNCHER_HEIGHT_PX = 50;
|
|
@@ -863,58 +1135,6 @@ function verticalAlignToBottomPx(align) {
|
|
|
863
1135
|
function launcherPopsDown(bottomPx) {
|
|
864
1136
|
return bottomPx + LAUNCHER_HEIGHT_PX / 2 > window.innerHeight / 2;
|
|
865
1137
|
}
|
|
866
|
-
|
|
867
|
-
// src/lib/agentMode.ts
|
|
868
|
-
var AGENT_MODE = {
|
|
869
|
-
Standard: "standard",
|
|
870
|
-
AlwaysOn: "always_on"
|
|
871
|
-
};
|
|
872
|
-
var AGENT_MODES = Object.values(AGENT_MODE);
|
|
873
|
-
|
|
874
|
-
// src/lib/sessionStatus.ts
|
|
875
|
-
var SESSION_STATUS = {
|
|
876
|
-
pending: "pending",
|
|
877
|
-
active: "active",
|
|
878
|
-
paused: "paused",
|
|
879
|
-
completed: "completed",
|
|
880
|
-
expired: "expired"
|
|
881
|
-
};
|
|
882
|
-
var SESSION_STATUSES = Object.values(SESSION_STATUS);
|
|
883
|
-
|
|
884
|
-
// src/lib/session.ts
|
|
885
|
-
function getResumableSessionId(currentSession, mode) {
|
|
886
|
-
if (!currentSession)
|
|
887
|
-
return;
|
|
888
|
-
const { id, status } = currentSession;
|
|
889
|
-
if (status === SESSION_STATUS.paused || status === SESSION_STATUS.active)
|
|
890
|
-
return id;
|
|
891
|
-
if (mode === AGENT_MODE.AlwaysOn && (status === SESSION_STATUS.expired || status === SESSION_STATUS.completed))
|
|
892
|
-
return id;
|
|
893
|
-
return;
|
|
894
|
-
}
|
|
895
|
-
function canResumeSession(currentSession, mode) {
|
|
896
|
-
return getResumableSessionId(currentSession, mode) !== undefined;
|
|
897
|
-
}
|
|
898
|
-
function getResumableSession(module) {
|
|
899
|
-
if (!module)
|
|
900
|
-
return null;
|
|
901
|
-
const id = getResumableSessionId(module.currentSession, module.mode);
|
|
902
|
-
return id ? { id, agentId: module.id } : null;
|
|
903
|
-
}
|
|
904
|
-
function getModuleSessionState(currentSession, mode) {
|
|
905
|
-
if (!currentSession)
|
|
906
|
-
return null;
|
|
907
|
-
if (canResumeSession(currentSession, mode))
|
|
908
|
-
return "resume";
|
|
909
|
-
if (mode === AGENT_MODE.Standard) {
|
|
910
|
-
const { status } = currentSession;
|
|
911
|
-
if (status === SESSION_STATUS.completed)
|
|
912
|
-
return "completed";
|
|
913
|
-
if (status === SESSION_STATUS.expired)
|
|
914
|
-
return "expired";
|
|
915
|
-
}
|
|
916
|
-
return null;
|
|
917
|
-
}
|
|
918
1138
|
// ../../node_modules/.bun/lucide-react@1.8.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/createLucideIcon.js
|
|
919
1139
|
import { forwardRef as forwardRef2, createElement as createElement3 } from "react";
|
|
920
1140
|
|
|
@@ -962,9 +1182,9 @@ var hasA11yProp = (props) => {
|
|
|
962
1182
|
};
|
|
963
1183
|
|
|
964
1184
|
// ../../node_modules/.bun/lucide-react@1.8.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/context.js
|
|
965
|
-
import { createContext as
|
|
966
|
-
var LucideContext =
|
|
967
|
-
var useLucideContext = () =>
|
|
1185
|
+
import { createContext as createContext3, useContext as useContext3, useMemo as useMemo3, createElement } from "react";
|
|
1186
|
+
var LucideContext = createContext3({});
|
|
1187
|
+
var useLucideContext = () => useContext3(LucideContext);
|
|
968
1188
|
|
|
969
1189
|
// ../../node_modules/.bun/lucide-react@1.8.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/Icon.js
|
|
970
1190
|
var Icon = forwardRef(({ color, size, strokeWidth, absoluteStrokeWidth, className = "", children, iconNode, ...rest }, ref) => {
|
|
@@ -1188,7 +1408,7 @@ var __iconNode23 = [
|
|
|
1188
1408
|
];
|
|
1189
1409
|
var X = createLucideIcon("x", __iconNode23);
|
|
1190
1410
|
// src/components/AgentCursor.tsx
|
|
1191
|
-
import { useContext as
|
|
1411
|
+
import { useContext as useContext4, useEffect as useEffect10, useLayoutEffect, useRef as useRef3, useState as useState9 } from "react";
|
|
1192
1412
|
|
|
1193
1413
|
// src/capture/elementRef.ts
|
|
1194
1414
|
function safeGetIframeDocument(iframe) {
|
|
@@ -1325,7 +1545,7 @@ function traceRing(path, durationMs, onFrame, onDone) {
|
|
|
1325
1545
|
}
|
|
1326
1546
|
|
|
1327
1547
|
// src/components/AgentCursor.tsx
|
|
1328
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1548
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
1329
1549
|
var Z_INDEX = 2147483646;
|
|
1330
1550
|
var BRAND_TEAL = "#2bc0ae";
|
|
1331
1551
|
var GLIDE_EASE = "cubic-bezier(0.45, 0, 0.25, 1)";
|
|
@@ -1370,19 +1590,19 @@ function AgentCursor({
|
|
|
1370
1590
|
target,
|
|
1371
1591
|
animated = false
|
|
1372
1592
|
}) {
|
|
1373
|
-
const ctx =
|
|
1374
|
-
const [cursor, setCursor] =
|
|
1375
|
-
const [glideMs, setGlideMs] =
|
|
1376
|
-
const [phase, setPhase] =
|
|
1377
|
-
const [ringBox, setRingBox] =
|
|
1378
|
-
const [clickPulse, setClickPulse] =
|
|
1379
|
-
const cursorElRef =
|
|
1380
|
-
const pathRef =
|
|
1381
|
-
const prevCursorRef =
|
|
1382
|
-
const traceRef =
|
|
1383
|
-
const timersRef =
|
|
1384
|
-
const trackFrameRef =
|
|
1385
|
-
const glideFrameRef =
|
|
1593
|
+
const ctx = useContext4(LiveAgentContext);
|
|
1594
|
+
const [cursor, setCursor] = useState9(null);
|
|
1595
|
+
const [glideMs, setGlideMs] = useState9(0);
|
|
1596
|
+
const [phase, setPhase] = useState9("idle");
|
|
1597
|
+
const [ringBox, setRingBox] = useState9(null);
|
|
1598
|
+
const [clickPulse, setClickPulse] = useState9(0);
|
|
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);
|
|
1386
1606
|
const clearTimers = () => {
|
|
1387
1607
|
for (const t of timersRef.current)
|
|
1388
1608
|
clearTimeout(t);
|
|
@@ -1498,7 +1718,7 @@ function AgentCursor({
|
|
|
1498
1718
|
});
|
|
1499
1719
|
return cancelAnimation;
|
|
1500
1720
|
}, [target, animated]);
|
|
1501
|
-
|
|
1721
|
+
useEffect10(() => {
|
|
1502
1722
|
if (!target || target.kind === "gesture" || phase === "idle")
|
|
1503
1723
|
return;
|
|
1504
1724
|
const track = () => {
|
|
@@ -1530,7 +1750,7 @@ function AgentCursor({
|
|
|
1530
1750
|
}
|
|
1531
1751
|
};
|
|
1532
1752
|
}, [target, phase]);
|
|
1533
|
-
|
|
1753
|
+
useEffect10(() => {
|
|
1534
1754
|
return () => {
|
|
1535
1755
|
traceRef.current?.cancel();
|
|
1536
1756
|
for (const t of timersRef.current)
|
|
@@ -1547,10 +1767,10 @@ function AgentCursor({
|
|
|
1547
1767
|
"data-skippr-private": "true",
|
|
1548
1768
|
"aria-hidden": "true",
|
|
1549
1769
|
children: [
|
|
1550
|
-
drawing && ringBox && /* @__PURE__ */
|
|
1770
|
+
drawing && ringBox && /* @__PURE__ */ jsx2("svg", {
|
|
1551
1771
|
"aria-hidden": "true",
|
|
1552
1772
|
style: { ...ringBoxStyle(ringBox, Z_INDEX), overflow: "visible" },
|
|
1553
|
-
children: /* @__PURE__ */
|
|
1773
|
+
children: /* @__PURE__ */ jsx2("path", {
|
|
1554
1774
|
ref: pathRef,
|
|
1555
1775
|
d: ringPathD(ringBox),
|
|
1556
1776
|
fill: "none",
|
|
@@ -1564,20 +1784,20 @@ function AgentCursor({
|
|
|
1564
1784
|
style: ringBoxStyle(ringBox, Z_INDEX),
|
|
1565
1785
|
className: "skippr:relative",
|
|
1566
1786
|
children: [
|
|
1567
|
-
/* @__PURE__ */
|
|
1787
|
+
/* @__PURE__ */ jsx2("div", {
|
|
1568
1788
|
className: "skippr:absolute skippr:inset-0 skippr:rounded-[1rem] skippr:border-2 skippr:border-[#2bc0ae] skippr:animate-skippr-annotation-pulse"
|
|
1569
1789
|
}),
|
|
1570
|
-
/* @__PURE__ */
|
|
1790
|
+
/* @__PURE__ */ jsx2("div", {
|
|
1571
1791
|
role: "status",
|
|
1572
1792
|
className: "skippr:absolute skippr:-bottom-9 skippr:left-1/2 skippr:-translate-x-1/2 skippr:flex skippr:items-center skippr:gap-1.5 skippr:rounded-full skippr:bg-[#2bc0ae] skippr:px-2.5 skippr:py-1 skippr:shadow-[0_4px_12px_rgba(0,0,0,0.12)]",
|
|
1573
|
-
children: /* @__PURE__ */
|
|
1793
|
+
children: /* @__PURE__ */ jsx2("span", {
|
|
1574
1794
|
className: "skippr:text-[11px] skippr:font-medium skippr:text-white skippr:whitespace-nowrap",
|
|
1575
1795
|
children: target.label
|
|
1576
1796
|
})
|
|
1577
1797
|
})
|
|
1578
1798
|
]
|
|
1579
1799
|
}),
|
|
1580
|
-
target.kind === "gesture" && /* @__PURE__ */
|
|
1800
|
+
target.kind === "gesture" && /* @__PURE__ */ jsx2("div", {
|
|
1581
1801
|
role: "status",
|
|
1582
1802
|
className: "skippr:fixed skippr:-translate-x-1/2 skippr:flex skippr:items-center skippr:gap-1.5 skippr:rounded-full skippr:bg-[#2bc0ae] skippr:px-2.5 skippr:py-1 skippr:shadow-[0_4px_12px_rgba(0,0,0,0.12)]",
|
|
1583
1803
|
style: {
|
|
@@ -1587,12 +1807,12 @@ function AgentCursor({
|
|
|
1587
1807
|
pointerEvents: "none",
|
|
1588
1808
|
transition: `left ${glideMs}ms ${GLIDE_EASE}, top ${glideMs}ms ${GLIDE_EASE}`
|
|
1589
1809
|
},
|
|
1590
|
-
children: /* @__PURE__ */
|
|
1810
|
+
children: /* @__PURE__ */ jsx2("span", {
|
|
1591
1811
|
className: "skippr:text-[11px] skippr:font-medium skippr:text-white skippr:whitespace-nowrap",
|
|
1592
1812
|
children: target.label
|
|
1593
1813
|
})
|
|
1594
1814
|
}),
|
|
1595
|
-
/* @__PURE__ */
|
|
1815
|
+
/* @__PURE__ */ jsx2("div", {
|
|
1596
1816
|
ref: cursorElRef,
|
|
1597
1817
|
style: {
|
|
1598
1818
|
position: "fixed",
|
|
@@ -1602,12 +1822,12 @@ function AgentCursor({
|
|
|
1602
1822
|
zIndex: Z_INDEX,
|
|
1603
1823
|
transition: `left ${glideMs}ms ${GLIDE_EASE}, top ${glideMs}ms ${GLIDE_EASE}`
|
|
1604
1824
|
},
|
|
1605
|
-
children: /* @__PURE__ */
|
|
1825
|
+
children: /* @__PURE__ */ jsx2(MousePointer2, {
|
|
1606
1826
|
className: `skippr:h-5 skippr:w-5 skippr:text-[#2bc0ae] skippr:drop-shadow-[0_2px_5px_rgba(0,0,0,0.4)] ${clickPulse > 0 ? "skippr:animate-skippr-press" : "skippr:animate-skippr-cursor-pop"}`,
|
|
1607
1827
|
fill: "currentColor"
|
|
1608
1828
|
}, clickPulse)
|
|
1609
1829
|
}),
|
|
1610
|
-
clickPulse > 0 && rippleCenter && /* @__PURE__ */
|
|
1830
|
+
clickPulse > 0 && rippleCenter && /* @__PURE__ */ jsx2("span", {
|
|
1611
1831
|
className: "skippr:fixed skippr:h-7 skippr:w-7 skippr:rounded-full skippr:bg-[#2bc0ae]/50 skippr:animate-skippr-click-ping",
|
|
1612
1832
|
style: {
|
|
1613
1833
|
left: `${rippleCenter.x}px`,
|
|
@@ -1621,14 +1841,14 @@ function AgentCursor({
|
|
|
1621
1841
|
}
|
|
1622
1842
|
|
|
1623
1843
|
// src/components/AutoStartMedia.tsx
|
|
1624
|
-
import { useConnectionState, useLocalParticipant } from "@livekit/components-react/hooks";
|
|
1844
|
+
import { useConnectionState, useLocalParticipant as useLocalParticipant2 } from "@livekit/components-react/hooks";
|
|
1625
1845
|
import { ConnectionState, Track } from "livekit-client";
|
|
1626
|
-
import { useEffect as
|
|
1846
|
+
import { useEffect as useEffect11, useRef as useRef4 } from "react";
|
|
1627
1847
|
function AutoStartMedia({ pendingScreenStream }) {
|
|
1628
|
-
const { localParticipant } =
|
|
1848
|
+
const { localParticipant } = useLocalParticipant2();
|
|
1629
1849
|
const connectionState = useConnectionState();
|
|
1630
|
-
const didStartRef =
|
|
1631
|
-
|
|
1850
|
+
const didStartRef = useRef4(false);
|
|
1851
|
+
useEffect11(() => {
|
|
1632
1852
|
if (didStartRef.current)
|
|
1633
1853
|
return;
|
|
1634
1854
|
if (connectionState !== ConnectionState.Connected)
|
|
@@ -1651,9 +1871,9 @@ function AutoStartMedia({ pendingScreenStream }) {
|
|
|
1651
1871
|
}
|
|
1652
1872
|
|
|
1653
1873
|
// src/components/DomCapture.tsx
|
|
1654
|
-
import { useConnectionState as useConnectionState2, useLocalParticipant as
|
|
1874
|
+
import { useConnectionState as useConnectionState2, useLocalParticipant as useLocalParticipant3 } from "@livekit/components-react/hooks";
|
|
1655
1875
|
import { ConnectionState as ConnectionState2, ScreenSharePresets, Track as Track2 } from "livekit-client";
|
|
1656
|
-
import { useEffect as
|
|
1876
|
+
import { useEffect as useEffect12, useRef as useRef5 } from "react";
|
|
1657
1877
|
|
|
1658
1878
|
// src/capture/a11yUtils.ts
|
|
1659
1879
|
var ROLE_BY_TAG = {
|
|
@@ -2268,7 +2488,7 @@ function subscribeActionsBusy(cb) {
|
|
|
2268
2488
|
|
|
2269
2489
|
// src/capture/domEvents.ts
|
|
2270
2490
|
var MUTATION_DEBOUNCE_MS = 250;
|
|
2271
|
-
var
|
|
2491
|
+
var textEncoder2 = new TextEncoder;
|
|
2272
2492
|
function isInsideWidget(target) {
|
|
2273
2493
|
if (!(target instanceof Node))
|
|
2274
2494
|
return false;
|
|
@@ -2294,7 +2514,7 @@ function installDomEventListeners(localParticipant, options = {}) {
|
|
|
2294
2514
|
const { onTriggerEvent } = options;
|
|
2295
2515
|
function publishDomEvent(event) {
|
|
2296
2516
|
try {
|
|
2297
|
-
localParticipant.publishData(
|
|
2517
|
+
localParticipant.publishData(textEncoder2.encode(JSON.stringify(event)), {
|
|
2298
2518
|
reliable: true,
|
|
2299
2519
|
topic: DOM_EVENTS_TOPIC
|
|
2300
2520
|
}).catch(() => {
|
|
@@ -2460,7 +2680,7 @@ var CAPTURE_BITRATE = 4000000;
|
|
|
2460
2680
|
var DOM_SNAPSHOT_GZIP_THRESHOLD_BYTES = 14000;
|
|
2461
2681
|
var MAX_CANVAS_DPR = 1.5;
|
|
2462
2682
|
var CONSECUTIVE_FAILURES_BEFORE_REPORT = 3;
|
|
2463
|
-
var
|
|
2683
|
+
var textEncoder3 = new TextEncoder;
|
|
2464
2684
|
function shouldIncludeInSnapshot(element) {
|
|
2465
2685
|
if (!(element instanceof Element))
|
|
2466
2686
|
return true;
|
|
@@ -2535,7 +2755,7 @@ async function buildDomSnapshotFrame() {
|
|
|
2535
2755
|
title: document.title,
|
|
2536
2756
|
capturedAt: new Date().toISOString()
|
|
2537
2757
|
});
|
|
2538
|
-
const snapshotBytes =
|
|
2758
|
+
const snapshotBytes = textEncoder3.encode(snapshotJson);
|
|
2539
2759
|
const { bytes, compressionFlag } = await gzipIfBeneficial(snapshotBytes);
|
|
2540
2760
|
const frame = new Uint8Array(bytes.byteLength + 1);
|
|
2541
2761
|
frame[0] = compressionFlag;
|
|
@@ -2544,7 +2764,7 @@ async function buildDomSnapshotFrame() {
|
|
|
2544
2764
|
}
|
|
2545
2765
|
function reportCaptureError(localParticipant) {
|
|
2546
2766
|
try {
|
|
2547
|
-
localParticipant.publishData(
|
|
2767
|
+
localParticipant.publishData(textEncoder3.encode(JSON.stringify({ type: "capture_error" })), {
|
|
2548
2768
|
reliable: true,
|
|
2549
2769
|
topic: DOM_SNAPSHOT_TOPIC
|
|
2550
2770
|
}).catch(() => {
|
|
@@ -2559,10 +2779,10 @@ async function unpublishAndStopTrack(localParticipant, videoTrack) {
|
|
|
2559
2779
|
videoTrack.stop();
|
|
2560
2780
|
}
|
|
2561
2781
|
function DomCapture() {
|
|
2562
|
-
const { localParticipant } =
|
|
2782
|
+
const { localParticipant } = useLocalParticipant3();
|
|
2563
2783
|
const connectionState = useConnectionState2();
|
|
2564
|
-
const didStartRef =
|
|
2565
|
-
|
|
2784
|
+
const didStartRef = useRef5(false);
|
|
2785
|
+
useEffect12(() => {
|
|
2566
2786
|
if (didStartRef.current)
|
|
2567
2787
|
return;
|
|
2568
2788
|
if (connectionState !== ConnectionState2.Connected)
|
|
@@ -2672,7 +2892,7 @@ function DomCapture() {
|
|
|
2672
2892
|
|
|
2673
2893
|
// src/components/HighlightOverlay.tsx
|
|
2674
2894
|
import { useDataChannel } from "@livekit/components-react/hooks";
|
|
2675
|
-
import { useCallback as
|
|
2895
|
+
import { useCallback as useCallback7, useEffect as useEffect13, useRef as useRef6 } from "react";
|
|
2676
2896
|
var HIGHLIGHT_AUTO_CLEAR_MS = 1e4;
|
|
2677
2897
|
var textDecoder = new TextDecoder;
|
|
2678
2898
|
function parseHighlightMessage(payload) {
|
|
@@ -2695,16 +2915,16 @@ function parseHighlightMessage(payload) {
|
|
|
2695
2915
|
}
|
|
2696
2916
|
}
|
|
2697
2917
|
function HighlightOverlay() {
|
|
2698
|
-
const targetRef =
|
|
2699
|
-
const autoClearRef =
|
|
2700
|
-
const clear =
|
|
2918
|
+
const targetRef = useRef6(null);
|
|
2919
|
+
const autoClearRef = useRef6(null);
|
|
2920
|
+
const clear = useCallback7(() => {
|
|
2701
2921
|
if (autoClearRef.current)
|
|
2702
2922
|
clearTimeout(autoClearRef.current);
|
|
2703
2923
|
autoClearRef.current = null;
|
|
2704
2924
|
targetRef.current = null;
|
|
2705
2925
|
clearCursorTarget("guide");
|
|
2706
2926
|
}, []);
|
|
2707
|
-
const onHighlightMessage =
|
|
2927
|
+
const onHighlightMessage = useCallback7((msg) => {
|
|
2708
2928
|
const parsed = parseHighlightMessage(msg.payload);
|
|
2709
2929
|
if (!parsed)
|
|
2710
2930
|
return;
|
|
@@ -2728,7 +2948,7 @@ function HighlightOverlay() {
|
|
|
2728
2948
|
autoClearRef.current = setTimeout(clear, HIGHLIGHT_AUTO_CLEAR_MS);
|
|
2729
2949
|
}, [clear]);
|
|
2730
2950
|
useDataChannel(HIGHLIGHT_TOPIC, onHighlightMessage);
|
|
2731
|
-
|
|
2951
|
+
useEffect13(() => {
|
|
2732
2952
|
const onClick = (event) => {
|
|
2733
2953
|
const target = targetRef.current;
|
|
2734
2954
|
const node = event.target;
|
|
@@ -2738,26 +2958,26 @@ function HighlightOverlay() {
|
|
|
2738
2958
|
document.addEventListener("click", onClick, { capture: true });
|
|
2739
2959
|
return () => document.removeEventListener("click", onClick, { capture: true });
|
|
2740
2960
|
}, [clear]);
|
|
2741
|
-
|
|
2961
|
+
useEffect13(() => clear, [clear]);
|
|
2742
2962
|
return null;
|
|
2743
2963
|
}
|
|
2744
2964
|
|
|
2745
2965
|
// src/components/MinimizedBubble.tsx
|
|
2746
|
-
import { useContext as
|
|
2966
|
+
import { useContext as useContext5, useEffect as useEffect15, useRef as useRef8, useState as useState10 } from "react";
|
|
2747
2967
|
|
|
2748
2968
|
// src/hooks/useLauncherDrag.ts
|
|
2749
|
-
import { useEffect as
|
|
2969
|
+
import { useEffect as useEffect14, useRef as useRef7 } from "react";
|
|
2750
2970
|
import { flushSync } from "react-dom";
|
|
2751
2971
|
var DRAG_THRESHOLD_PX = 5;
|
|
2752
2972
|
function useLauncherDrag(containerRef, onDrop, followRefs, reportDragging) {
|
|
2753
|
-
const wasDraggedRef =
|
|
2754
|
-
const onDropRef =
|
|
2973
|
+
const wasDraggedRef = useRef7(false);
|
|
2974
|
+
const onDropRef = useRef7(onDrop);
|
|
2755
2975
|
onDropRef.current = onDrop;
|
|
2756
|
-
const followTargetsRef =
|
|
2976
|
+
const followTargetsRef = useRef7(followRefs);
|
|
2757
2977
|
followTargetsRef.current = followRefs;
|
|
2758
|
-
const reportDraggingRef =
|
|
2978
|
+
const reportDraggingRef = useRef7(reportDragging);
|
|
2759
2979
|
reportDraggingRef.current = reportDragging;
|
|
2760
|
-
|
|
2980
|
+
useEffect14(() => {
|
|
2761
2981
|
const el = containerRef.current;
|
|
2762
2982
|
if (!el)
|
|
2763
2983
|
return;
|
|
@@ -2906,7 +3126,7 @@ function cn(...inputs) {
|
|
|
2906
3126
|
}
|
|
2907
3127
|
|
|
2908
3128
|
// src/components/AdoptionBubble.tsx
|
|
2909
|
-
import { jsx as
|
|
3129
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2910
3130
|
function AdoptionBubble({
|
|
2911
3131
|
goal,
|
|
2912
3132
|
onAttend,
|
|
@@ -2914,7 +3134,7 @@ function AdoptionBubble({
|
|
|
2914
3134
|
exitDelayMs = 0,
|
|
2915
3135
|
hidden = false
|
|
2916
3136
|
}) {
|
|
2917
|
-
return /* @__PURE__ */
|
|
3137
|
+
return /* @__PURE__ */ jsx3("div", {
|
|
2918
3138
|
style: {
|
|
2919
3139
|
animationDelay: `${appearDelayMs}ms`,
|
|
2920
3140
|
transitionDelay: hidden ? `${exitDelayMs}ms` : "0ms"
|
|
@@ -2925,18 +3145,18 @@ function AdoptionBubble({
|
|
|
2925
3145
|
onClick: () => onAttend(goal),
|
|
2926
3146
|
className: cn("skippr:flex skippr:max-w-72 skippr:items-center skippr:gap-2", "skippr:rounded-[14px] skippr:bg-amber-50 skippr:py-1.5 skippr:pr-3 skippr:pl-1.5", "skippr:text-left skippr:shadow-[0_8px_24px_rgba(0,0,0,0.18)]", "skippr:transition-colors skippr:cursor-pointer skippr:hover:bg-amber-100", "skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-bubble/60"),
|
|
2927
3147
|
children: [
|
|
2928
|
-
/* @__PURE__ */
|
|
3148
|
+
/* @__PURE__ */ jsx3("span", {
|
|
2929
3149
|
className: cn("skippr:flex skippr:h-6 skippr:w-6 skippr:shrink-0 skippr:items-center skippr:justify-center", "skippr:text-amber-700"),
|
|
2930
|
-
children: /* @__PURE__ */
|
|
3150
|
+
children: /* @__PURE__ */ jsx3(Lightbulb, {
|
|
2931
3151
|
className: "skippr:h-3.5 skippr:w-3.5",
|
|
2932
3152
|
fill: "currentColor"
|
|
2933
3153
|
})
|
|
2934
3154
|
}),
|
|
2935
|
-
/* @__PURE__ */
|
|
3155
|
+
/* @__PURE__ */ jsx3("span", {
|
|
2936
3156
|
className: "skippr:min-w-0 skippr:truncate skippr:text-[13px] skippr:font-semibold skippr:text-amber-950",
|
|
2937
3157
|
children: goal.displayMessage
|
|
2938
3158
|
}),
|
|
2939
|
-
/* @__PURE__ */
|
|
3159
|
+
/* @__PURE__ */ jsx3(ArrowRight, {
|
|
2940
3160
|
className: "skippr:h-3.5 skippr:w-3.5 skippr:shrink-0 skippr:text-amber-700"
|
|
2941
3161
|
})
|
|
2942
3162
|
]
|
|
@@ -2945,12 +3165,12 @@ function AdoptionBubble({
|
|
|
2945
3165
|
}
|
|
2946
3166
|
|
|
2947
3167
|
// src/components/ModulePill.tsx
|
|
2948
|
-
import { jsx as
|
|
3168
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2949
3169
|
var RING_RADIUS = 8;
|
|
2950
3170
|
var RING_CIRCUMFERENCE = 2 * Math.PI * RING_RADIUS;
|
|
2951
|
-
function ModulePill({ module, onSelect
|
|
2952
|
-
const completedPhases =
|
|
2953
|
-
const totalPhases =
|
|
3171
|
+
function ModulePill({ module, onSelect }) {
|
|
3172
|
+
const completedPhases = module.currentSession?.currentPhaseIndex ?? 0;
|
|
3173
|
+
const totalPhases = module.totalPhases;
|
|
2954
3174
|
const showProgress = module.mode !== AGENT_MODE.AlwaysOn && totalPhases > 0;
|
|
2955
3175
|
const progressFraction = showProgress ? Math.min(completedPhases / totalPhases, 1) : 0;
|
|
2956
3176
|
return /* @__PURE__ */ jsxs3("button", {
|
|
@@ -2958,16 +3178,12 @@ function ModulePill({ module, onSelect, progress, isLive = false, label }) {
|
|
|
2958
3178
|
onClick: () => onSelect(module.id),
|
|
2959
3179
|
className: cn("skippr:flex skippr:w-40 skippr:items-center skippr:gap-1.5 skippr:whitespace-nowrap", "skippr:rounded-[14px] skippr:bg-white skippr:px-3 skippr:py-1.5", "skippr:text-[13px] skippr:font-medium skippr:text-black", "skippr:shadow-[0_8px_24px_rgba(0,0,0,0.18)]", "skippr:transition-colors skippr:cursor-pointer skippr:hover:bg-neutral-100", "skippr:animate-[skippr-bubble-in_0.28s_ease-out]", "skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-bubble/60"),
|
|
2960
3180
|
children: [
|
|
2961
|
-
|
|
2962
|
-
"aria-hidden": "true",
|
|
2963
|
-
className: "skippr:size-[6px] skippr:shrink-0 skippr:rounded-full skippr:bg-emerald-500 skippr:animate-pulse skippr:motion-reduce:animate-none"
|
|
2964
|
-
}),
|
|
2965
|
-
showProgress && !isLive && /* @__PURE__ */ jsxs3("svg", {
|
|
3181
|
+
showProgress && /* @__PURE__ */ jsxs3("svg", {
|
|
2966
3182
|
viewBox: "0 0 20 20",
|
|
2967
3183
|
className: "skippr:size-4 skippr:shrink-0 skippr:-rotate-90",
|
|
2968
3184
|
"aria-hidden": "true",
|
|
2969
3185
|
children: [
|
|
2970
|
-
/* @__PURE__ */
|
|
3186
|
+
/* @__PURE__ */ jsx4("circle", {
|
|
2971
3187
|
cx: "10",
|
|
2972
3188
|
cy: "10",
|
|
2973
3189
|
r: RING_RADIUS,
|
|
@@ -2975,7 +3191,7 @@ function ModulePill({ module, onSelect, progress, isLive = false, label }) {
|
|
|
2975
3191
|
strokeWidth: "2.5",
|
|
2976
3192
|
className: "skippr:stroke-black/15"
|
|
2977
3193
|
}),
|
|
2978
|
-
/* @__PURE__ */
|
|
3194
|
+
/* @__PURE__ */ jsx4("circle", {
|
|
2979
3195
|
cx: "10",
|
|
2980
3196
|
cy: "10",
|
|
2981
3197
|
r: RING_RADIUS,
|
|
@@ -2988,9 +3204,9 @@ function ModulePill({ module, onSelect, progress, isLive = false, label }) {
|
|
|
2988
3204
|
})
|
|
2989
3205
|
]
|
|
2990
3206
|
}),
|
|
2991
|
-
/* @__PURE__ */
|
|
3207
|
+
/* @__PURE__ */ jsx4("span", {
|
|
2992
3208
|
className: "skippr:min-w-0 skippr:flex-1 skippr:truncate skippr:text-left",
|
|
2993
|
-
children:
|
|
3209
|
+
children: module.name
|
|
2994
3210
|
}),
|
|
2995
3211
|
showProgress && /* @__PURE__ */ jsxs3("span", {
|
|
2996
3212
|
className: cn("skippr:ml-0.5 skippr:inline-flex skippr:shrink-0 skippr:items-center skippr:gap-1 skippr:rounded-full", "skippr:bg-black/[0.07] skippr:px-1.5 skippr:py-0.5", "skippr:text-[10px] skippr:font-semibold"),
|
|
@@ -3005,29 +3221,86 @@ function ModulePill({ module, onSelect, progress, isLive = false, label }) {
|
|
|
3005
3221
|
}
|
|
3006
3222
|
|
|
3007
3223
|
// src/components/MinimizedBubble.tsx
|
|
3008
|
-
import { jsx as
|
|
3224
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3009
3225
|
var GOALS_AUTO_HIDE_MS = 1e4;
|
|
3010
3226
|
var GOAL_FADE_OUT_MS = 300;
|
|
3011
3227
|
var GOAL_APPEAR_STAGGER_MS = 150;
|
|
3012
3228
|
var GOAL_EXIT_STAGGER_MS = 250;
|
|
3013
3229
|
var MAX_GOAL_BUBBLES = 3;
|
|
3014
3230
|
var MAX_MODULE_PILLS = 3;
|
|
3015
|
-
function
|
|
3016
|
-
return /* @__PURE__ */
|
|
3231
|
+
function SkipprMark({ onStart }) {
|
|
3232
|
+
return /* @__PURE__ */ jsx5("button", {
|
|
3017
3233
|
type: "button",
|
|
3018
|
-
onClick,
|
|
3234
|
+
onClick: onStart,
|
|
3019
3235
|
"aria-label": "Ask Me Anything",
|
|
3020
|
-
className:
|
|
3021
|
-
children: /* @__PURE__ */
|
|
3236
|
+
className: "skippr:flex skippr:h-[36px] skippr:w-[36px] skippr:shrink-0 skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:bg-transparent skippr:p-0",
|
|
3237
|
+
children: /* @__PURE__ */ jsx5("svg", {
|
|
3022
3238
|
viewBox: "0 0 15.4044 18.4853",
|
|
3023
|
-
className:
|
|
3239
|
+
className: "skippr:h-[18.5px] skippr:w-[15.4px]",
|
|
3024
3240
|
fill: "none",
|
|
3025
3241
|
"aria-hidden": "true",
|
|
3026
|
-
children: /* @__PURE__ */
|
|
3242
|
+
children: /* @__PURE__ */ jsx5("path", {
|
|
3027
3243
|
d: "M2.25789 0.295419C1.33925 -0.413932 0 0.234459 0 1.38715V17.0972C0 18.4106 1.67407 18.987 2.49664 17.9562L6.40435 13.061C6.54853 12.8805 6.73209 12.7348 6.94126 12.6347C7.15043 12.5345 7.37978 12.4826 7.6121 12.4828H14.0025C15.3343 12.4828 15.9134 10.8128 14.8614 10.0037L2.25789 0.295419Z",
|
|
3028
3244
|
className: "skippr:fill-brand"
|
|
3029
3245
|
})
|
|
3030
|
-
})
|
|
3246
|
+
})
|
|
3247
|
+
});
|
|
3248
|
+
}
|
|
3249
|
+
function ChatButton({
|
|
3250
|
+
revealed,
|
|
3251
|
+
position,
|
|
3252
|
+
onClick
|
|
3253
|
+
}) {
|
|
3254
|
+
return /* @__PURE__ */ jsx5("button", {
|
|
3255
|
+
type: "button",
|
|
3256
|
+
onClick,
|
|
3257
|
+
"aria-label": "Open chat",
|
|
3258
|
+
tabIndex: revealed ? 0 : -1,
|
|
3259
|
+
className: cn("skippr:h-[36px] skippr:shrink-0 skippr:overflow-hidden skippr:p-0", "skippr:transition-all skippr:duration-[400ms] skippr:ease-[cubic-bezier(0.22,1,0.36,1)]", position === "right" ? "skippr:order-last" : "skippr:order-first"),
|
|
3260
|
+
style: {
|
|
3261
|
+
width: revealed ? 36 : 0,
|
|
3262
|
+
opacity: revealed ? 1 : 0,
|
|
3263
|
+
transform: revealed ? "scale(1)" : "scale(0.55)",
|
|
3264
|
+
cursor: revealed ? "pointer" : "default"
|
|
3265
|
+
},
|
|
3266
|
+
children: /* @__PURE__ */ jsx5("span", {
|
|
3267
|
+
className: "skippr:flex skippr:h-[36px] skippr:w-[36px] skippr:items-center skippr:justify-center skippr:rounded-[11px] skippr:bg-white",
|
|
3268
|
+
children: /* @__PURE__ */ jsx5("svg", {
|
|
3269
|
+
width: "18",
|
|
3270
|
+
height: "18",
|
|
3271
|
+
viewBox: "0 0 24 24",
|
|
3272
|
+
fill: "none",
|
|
3273
|
+
stroke: "#1c1f2a",
|
|
3274
|
+
strokeWidth: "2",
|
|
3275
|
+
strokeLinecap: "round",
|
|
3276
|
+
strokeLinejoin: "round",
|
|
3277
|
+
"aria-hidden": "true",
|
|
3278
|
+
children: /* @__PURE__ */ jsx5("path", {
|
|
3279
|
+
d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
|
|
3280
|
+
})
|
|
3281
|
+
})
|
|
3282
|
+
})
|
|
3283
|
+
});
|
|
3284
|
+
}
|
|
3285
|
+
function IdleLauncher({
|
|
3286
|
+
position,
|
|
3287
|
+
isHovered,
|
|
3288
|
+
onStart,
|
|
3289
|
+
onChat
|
|
3290
|
+
}) {
|
|
3291
|
+
return /* @__PURE__ */ jsxs4("div", {
|
|
3292
|
+
className: cn("skippr:flex skippr:h-[48px] skippr:items-center", "skippr:bg-launcher skippr:p-1.5 skippr:shadow-[-6px_8px_30px_rgba(15,18,26,0.32)]", "skippr:[animation:skippr-orb-in_320ms_cubic-bezier(0.34,1.3,0.64,1)]", "skippr:transition-transform skippr:duration-[400ms] skippr:ease-[cubic-bezier(0.22,1,0.36,1)]", position === "right" ? "skippr:rounded-l-[18px] skippr:origin-right" : "skippr:rounded-r-[18px] skippr:origin-left", position === "right" ? isHovered ? "skippr:translate-x-3" : "skippr:translate-x-7" : isHovered ? "skippr:-translate-x-3" : "skippr:-translate-x-7"),
|
|
3293
|
+
style: { gap: isHovered ? 8 : 0 },
|
|
3294
|
+
children: [
|
|
3295
|
+
/* @__PURE__ */ jsx5(ChatButton, {
|
|
3296
|
+
revealed: isHovered,
|
|
3297
|
+
position,
|
|
3298
|
+
onClick: onChat
|
|
3299
|
+
}),
|
|
3300
|
+
/* @__PURE__ */ jsx5(SkipprMark, {
|
|
3301
|
+
onStart
|
|
3302
|
+
})
|
|
3303
|
+
]
|
|
3031
3304
|
});
|
|
3032
3305
|
}
|
|
3033
3306
|
function WelcomeBubble({
|
|
@@ -3037,7 +3310,7 @@ function WelcomeBubble({
|
|
|
3037
3310
|
onDismiss,
|
|
3038
3311
|
onClick
|
|
3039
3312
|
}) {
|
|
3040
|
-
|
|
3313
|
+
useEffect15(() => {
|
|
3041
3314
|
const timer = setTimeout(onDismiss, 5000);
|
|
3042
3315
|
return () => clearTimeout(timer);
|
|
3043
3316
|
}, [onDismiss]);
|
|
@@ -3048,7 +3321,7 @@ function WelcomeBubble({
|
|
|
3048
3321
|
"aria-label": "Dismiss",
|
|
3049
3322
|
children: [
|
|
3050
3323
|
message,
|
|
3051
|
-
/* @__PURE__ */
|
|
3324
|
+
/* @__PURE__ */ jsx5("span", {
|
|
3052
3325
|
className: cn("skippr:absolute skippr:size-2.5", "skippr:border-l skippr:border-t skippr:border-border skippr:bg-card", popsDown ? "skippr:bottom-full skippr:rotate-45 skippr:-mb-[5px]" : "skippr:top-full skippr:rotate-[225deg] skippr:-mt-[5px]", position === "right" ? "skippr:right-5" : "skippr:left-5")
|
|
3053
3326
|
})
|
|
3054
3327
|
]
|
|
@@ -3059,7 +3332,7 @@ function MinimizedBubble({
|
|
|
3059
3332
|
welcomeDismissed,
|
|
3060
3333
|
onDismissWelcome
|
|
3061
3334
|
}) {
|
|
3062
|
-
const ctx =
|
|
3335
|
+
const ctx = useContext5(LiveAgentContext);
|
|
3063
3336
|
if (!ctx) {
|
|
3064
3337
|
throw new Error("MinimizedBubble must be used within a <LiveAgent> provider");
|
|
3065
3338
|
}
|
|
@@ -3072,19 +3345,22 @@ function MinimizedBubble({
|
|
|
3072
3345
|
startAdoptionSession,
|
|
3073
3346
|
isAuthenticated,
|
|
3074
3347
|
displayModules,
|
|
3348
|
+
defaultAgentId,
|
|
3349
|
+
startDefaultSession,
|
|
3075
3350
|
hasResolvedModules,
|
|
3076
3351
|
isLoadingModules,
|
|
3077
3352
|
selectModule,
|
|
3078
3353
|
expandPanel,
|
|
3354
|
+
setSidebarTab,
|
|
3079
3355
|
commitLauncherDrop
|
|
3080
3356
|
} = ctx;
|
|
3081
|
-
const [goalsAutoHidden, setGoalsAutoHidden] =
|
|
3082
|
-
const [isLauncherHovered, setIsLauncherHovered] =
|
|
3083
|
-
const [visitHref, setVisitHref] =
|
|
3084
|
-
const revealedHrefRef =
|
|
3085
|
-
const hoverContainerRef =
|
|
3086
|
-
|
|
3087
|
-
|
|
3357
|
+
const [goalsAutoHidden, setGoalsAutoHidden] = useState10(false);
|
|
3358
|
+
const [isLauncherHovered, setIsLauncherHovered] = useState10(false);
|
|
3359
|
+
const [visitHref, setVisitHref] = useState10(() => window.location.href);
|
|
3360
|
+
const revealedHrefRef = useRef8(null);
|
|
3361
|
+
const hoverContainerRef = useRef8(null);
|
|
3362
|
+
useEffect15(() => subscribeToLocationChange(() => setVisitHref(window.location.href)), []);
|
|
3363
|
+
useEffect15(() => {
|
|
3088
3364
|
const el = hoverContainerRef.current;
|
|
3089
3365
|
if (!el)
|
|
3090
3366
|
return;
|
|
@@ -3102,12 +3378,11 @@ function MinimizedBubble({
|
|
|
3102
3378
|
const state = getModuleSessionState(module.currentSession, module.mode);
|
|
3103
3379
|
return state !== "completed" && state !== "expired";
|
|
3104
3380
|
});
|
|
3105
|
-
const alwaysOnModule = actionableModules.find((module) => module.mode === AGENT_MODE.AlwaysOn);
|
|
3106
3381
|
const pillCandidates = actionableModules.filter((module) => module.mode !== AGENT_MODE.AlwaysOn);
|
|
3107
3382
|
const onboardingModule = pillCandidates.find((module) => module.type === "onboarding");
|
|
3108
3383
|
const modulePills = onboardingModule ? [onboardingModule] : pillCandidates.slice(0, MAX_MODULE_PILLS).reverse();
|
|
3109
3384
|
const goalsEligible = adoptionGoals.length > 0 && !onboardingModule && hasResolvedModules;
|
|
3110
|
-
|
|
3385
|
+
useEffect15(() => {
|
|
3111
3386
|
if (!goalsEligible)
|
|
3112
3387
|
return;
|
|
3113
3388
|
if (revealedHrefRef.current === visitHref) {
|
|
@@ -3121,8 +3396,8 @@ function MinimizedBubble({
|
|
|
3121
3396
|
}, [goalsEligible, visitHref]);
|
|
3122
3397
|
const matchedGoals = goalsEligible ? adoptionGoals.slice(0, MAX_GOAL_BUBBLES) : [];
|
|
3123
3398
|
const goalsHidden = goalsAutoHidden && !isLauncherHovered;
|
|
3124
|
-
const [goalsUnmounted, setGoalsUnmounted] =
|
|
3125
|
-
|
|
3399
|
+
const [goalsUnmounted, setGoalsUnmounted] = useState10(false);
|
|
3400
|
+
useEffect15(() => {
|
|
3126
3401
|
if (!goalsHidden) {
|
|
3127
3402
|
setGoalsUnmounted(false);
|
|
3128
3403
|
return;
|
|
@@ -3132,12 +3407,18 @@ function MinimizedBubble({
|
|
|
3132
3407
|
return () => clearTimeout(timer);
|
|
3133
3408
|
}, [goalsHidden]);
|
|
3134
3409
|
const visibleGoals = goalsUnmounted ? [] : matchedGoals;
|
|
3410
|
+
const openChat = (e) => {
|
|
3411
|
+
e.stopPropagation();
|
|
3412
|
+
if (wasDraggedRef.current)
|
|
3413
|
+
return;
|
|
3414
|
+
setSidebarTab("chat");
|
|
3415
|
+
expandPanel();
|
|
3416
|
+
};
|
|
3135
3417
|
const launchDefaultSession = () => {
|
|
3136
3418
|
if (wasDraggedRef.current || isStarting || isLoadingModules)
|
|
3137
3419
|
return;
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
selectModule(target.id);
|
|
3420
|
+
if (isAuthenticated && defaultAgentId) {
|
|
3421
|
+
startDefaultSession();
|
|
3141
3422
|
} else {
|
|
3142
3423
|
expandPanel();
|
|
3143
3424
|
}
|
|
@@ -3150,7 +3431,7 @@ function MinimizedBubble({
|
|
|
3150
3431
|
(modulePills.length > 0 || visibleGoals.length > 0) && /* @__PURE__ */ jsxs4("div", {
|
|
3151
3432
|
className: cn("skippr:absolute skippr:gap-2", popsDown ? "skippr:top-full skippr:mt-3 skippr:flex skippr:flex-col-reverse" : "skippr:bottom-full skippr:mb-3 skippr:flex skippr:flex-col", position === "right" ? "skippr:right-0 skippr:items-end" : "skippr:left-0 skippr:items-start"),
|
|
3152
3433
|
children: [
|
|
3153
|
-
visibleGoals.map((goal, index2) => /* @__PURE__ */
|
|
3434
|
+
visibleGoals.map((goal, index2) => /* @__PURE__ */ jsx5(AdoptionBubble, {
|
|
3154
3435
|
goal,
|
|
3155
3436
|
onAttend: (attended) => {
|
|
3156
3437
|
if (!wasDraggedRef.current)
|
|
@@ -3160,7 +3441,7 @@ function MinimizedBubble({
|
|
|
3160
3441
|
exitDelayMs: (visibleGoals.length - 1 - index2) * GOAL_EXIT_STAGGER_MS,
|
|
3161
3442
|
hidden: goalsHidden
|
|
3162
3443
|
}, goal.goalId)),
|
|
3163
|
-
modulePills.map((module) => /* @__PURE__ */
|
|
3444
|
+
modulePills.map((module) => /* @__PURE__ */ jsx5(ModulePill, {
|
|
3164
3445
|
module,
|
|
3165
3446
|
onSelect: (id) => {
|
|
3166
3447
|
if (!wasDraggedRef.current)
|
|
@@ -3169,7 +3450,7 @@ function MinimizedBubble({
|
|
|
3169
3450
|
}, module.id))
|
|
3170
3451
|
]
|
|
3171
3452
|
}),
|
|
3172
|
-
welcomeMessage && !welcomeDismissed && adoptionGoals.length === 0 && modulePills.length === 0 && /* @__PURE__ */
|
|
3453
|
+
welcomeMessage && !welcomeDismissed && adoptionGoals.length === 0 && modulePills.length === 0 && /* @__PURE__ */ jsx5(WelcomeBubble, {
|
|
3173
3454
|
message: welcomeMessage,
|
|
3174
3455
|
position,
|
|
3175
3456
|
popsDown,
|
|
@@ -3179,9 +3460,11 @@ function MinimizedBubble({
|
|
|
3179
3460
|
onDismissWelcome();
|
|
3180
3461
|
}
|
|
3181
3462
|
}),
|
|
3182
|
-
/* @__PURE__ */
|
|
3463
|
+
/* @__PURE__ */ jsx5(IdleLauncher, {
|
|
3183
3464
|
position,
|
|
3184
|
-
|
|
3465
|
+
isHovered: isLauncherHovered,
|
|
3466
|
+
onStart: launchDefaultSession,
|
|
3467
|
+
onChat: openChat
|
|
3185
3468
|
})
|
|
3186
3469
|
]
|
|
3187
3470
|
});
|
|
@@ -3189,7 +3472,7 @@ function MinimizedBubble({
|
|
|
3189
3472
|
|
|
3190
3473
|
// src/components/PageActionHandler.tsx
|
|
3191
3474
|
import { useDataChannel as useDataChannel2 } from "@livekit/components-react/hooks";
|
|
3192
|
-
import { useCallback as
|
|
3475
|
+
import { useCallback as useCallback8, useEffect as useEffect16, useRef as useRef9 } from "react";
|
|
3193
3476
|
var STEP_MAX_WAIT_MS = 5000;
|
|
3194
3477
|
var POST_ACTION_SETTLE_SNAPSHOT_MS = 300;
|
|
3195
3478
|
var textDecoder2 = new TextDecoder;
|
|
@@ -3406,12 +3689,12 @@ function labelFor(action) {
|
|
|
3406
3689
|
}
|
|
3407
3690
|
}
|
|
3408
3691
|
function PageActionHandler() {
|
|
3409
|
-
const mountedRef =
|
|
3410
|
-
const queueRef =
|
|
3411
|
-
const drainingRef =
|
|
3412
|
-
const settleTimerRef =
|
|
3413
|
-
const endStepRef =
|
|
3414
|
-
const runStep =
|
|
3692
|
+
const mountedRef = useRef9(true);
|
|
3693
|
+
const queueRef = useRef9([]);
|
|
3694
|
+
const drainingRef = useRef9(false);
|
|
3695
|
+
const settleTimerRef = useRef9(null);
|
|
3696
|
+
const endStepRef = useRef9(null);
|
|
3697
|
+
const runStep = useCallback8((action) => {
|
|
3415
3698
|
return new Promise((resolve) => {
|
|
3416
3699
|
if (action.type === "scroll_page") {
|
|
3417
3700
|
let scrolled = false;
|
|
@@ -3480,7 +3763,7 @@ function PageActionHandler() {
|
|
|
3480
3763
|
});
|
|
3481
3764
|
});
|
|
3482
3765
|
}, []);
|
|
3483
|
-
const drain =
|
|
3766
|
+
const drain = useCallback8(async () => {
|
|
3484
3767
|
if (drainingRef.current)
|
|
3485
3768
|
return;
|
|
3486
3769
|
drainingRef.current = true;
|
|
@@ -3511,14 +3794,14 @@ function PageActionHandler() {
|
|
|
3511
3794
|
}
|
|
3512
3795
|
}
|
|
3513
3796
|
}, [runStep]);
|
|
3514
|
-
const onMessage =
|
|
3797
|
+
const onMessage = useCallback8((msg) => {
|
|
3515
3798
|
const action = parsePageAction(msg.payload);
|
|
3516
3799
|
if (!action)
|
|
3517
3800
|
return;
|
|
3518
3801
|
queueRef.current.push(action);
|
|
3519
3802
|
drain();
|
|
3520
3803
|
}, [drain]);
|
|
3521
|
-
|
|
3804
|
+
useEffect16(() => {
|
|
3522
3805
|
mountedRef.current = true;
|
|
3523
3806
|
drainingRef.current = false;
|
|
3524
3807
|
return () => {
|
|
@@ -3530,7 +3813,7 @@ function PageActionHandler() {
|
|
|
3530
3813
|
setActionsBusy(false);
|
|
3531
3814
|
};
|
|
3532
3815
|
}, []);
|
|
3533
|
-
|
|
3816
|
+
useEffect16(() => {
|
|
3534
3817
|
return onActionsPausedChange((paused) => {
|
|
3535
3818
|
if (paused) {
|
|
3536
3819
|
clearCursorTarget("act");
|
|
@@ -3546,25 +3829,25 @@ function PageActionHandler() {
|
|
|
3546
3829
|
}
|
|
3547
3830
|
|
|
3548
3831
|
// src/components/SessionControlBar.tsx
|
|
3549
|
-
import { useContext as useContext6, useEffect as
|
|
3832
|
+
import { useContext as useContext6, useEffect as useEffect19 } from "react";
|
|
3550
3833
|
|
|
3551
3834
|
// src/hooks/useActionControl.ts
|
|
3552
|
-
import { useLocalParticipant as
|
|
3553
|
-
import { useCallback as
|
|
3554
|
-
var
|
|
3835
|
+
import { useLocalParticipant as useLocalParticipant4 } from "@livekit/components-react/hooks";
|
|
3836
|
+
import { useCallback as useCallback9, useEffect as useEffect17, useState as useState11 } from "react";
|
|
3837
|
+
var textEncoder4 = new TextEncoder;
|
|
3555
3838
|
function useActionControl() {
|
|
3556
|
-
const { localParticipant } =
|
|
3839
|
+
const { localParticipant } = useLocalParticipant4();
|
|
3557
3840
|
const plan = usePlanUpdates();
|
|
3558
|
-
const [busy, setBusy] =
|
|
3559
|
-
const [actionsPaused2, setPaused] =
|
|
3560
|
-
|
|
3841
|
+
const [busy, setBusy] = useState11(isActionsBusy);
|
|
3842
|
+
const [actionsPaused2, setPaused] = useState11(false);
|
|
3843
|
+
useEffect17(() => subscribeActionsBusy(setBusy), []);
|
|
3561
3844
|
const actionsActive = busy || plan?.state === "executing";
|
|
3562
|
-
const togglePaused =
|
|
3845
|
+
const togglePaused = useCallback9(async () => {
|
|
3563
3846
|
const next = !actionsPaused2;
|
|
3564
3847
|
setPaused(next);
|
|
3565
3848
|
setActionsPaused(next);
|
|
3566
3849
|
try {
|
|
3567
|
-
await localParticipant.publishData(
|
|
3850
|
+
await localParticipant.publishData(textEncoder4.encode(JSON.stringify({ type: next ? "pause" : "resume" })), { reliable: true, topic: ACTION_CONTROL_TOPIC });
|
|
3568
3851
|
} catch (error) {
|
|
3569
3852
|
console.error("Failed to send action pause/resume:", error);
|
|
3570
3853
|
}
|
|
@@ -3585,13 +3868,13 @@ function useAgentVoiceState() {
|
|
|
3585
3868
|
}
|
|
3586
3869
|
|
|
3587
3870
|
// src/hooks/useAudioLevelBars.ts
|
|
3588
|
-
import { useEffect as
|
|
3871
|
+
import { useEffect as useEffect18, useRef as useRef10, useState as useState12 } from "react";
|
|
3589
3872
|
var TALKING_LEVEL_THRESHOLD = 0.2;
|
|
3590
3873
|
var TALKING_HOLD_MS = 400;
|
|
3591
3874
|
function useAudioLevelBars(mediaStreamTrack, { barCount, idleHeightPx, maxGrowthPx, noiseGate }) {
|
|
3592
|
-
const barRefs =
|
|
3593
|
-
const [isTalking, setIsTalking] =
|
|
3594
|
-
|
|
3875
|
+
const barRefs = useRef10([]);
|
|
3876
|
+
const [isTalking, setIsTalking] = useState12(false);
|
|
3877
|
+
useEffect18(() => {
|
|
3595
3878
|
if (!mediaStreamTrack) {
|
|
3596
3879
|
for (const bar of barRefs.current) {
|
|
3597
3880
|
if (bar)
|
|
@@ -3642,26 +3925,26 @@ function useAudioLevelBars(mediaStreamTrack, { barCount, idleHeightPx, maxGrowth
|
|
|
3642
3925
|
}
|
|
3643
3926
|
|
|
3644
3927
|
// src/hooks/useMediaControls.ts
|
|
3645
|
-
import { useLocalParticipant as
|
|
3928
|
+
import { useLocalParticipant as useLocalParticipant5 } from "@livekit/components-react/hooks";
|
|
3646
3929
|
import { ScreenSharePresets as ScreenSharePresets2 } from "livekit-client";
|
|
3647
|
-
import { useCallback as
|
|
3930
|
+
import { useCallback as useCallback10 } from "react";
|
|
3648
3931
|
var SCREEN_SHARE_OPTIONS = {
|
|
3649
3932
|
video: { displaySurface: "browser" },
|
|
3650
3933
|
resolution: ScreenSharePresets2.h720fps30.resolution,
|
|
3651
3934
|
contentHint: "detail"
|
|
3652
3935
|
};
|
|
3653
3936
|
function useMediaControls() {
|
|
3654
|
-
const { localParticipant } =
|
|
3937
|
+
const { localParticipant } = useLocalParticipant5();
|
|
3655
3938
|
const isMuted = !localParticipant.isMicrophoneEnabled;
|
|
3656
3939
|
const isScreenSharing = localParticipant.isScreenShareEnabled;
|
|
3657
|
-
const toggleMute =
|
|
3940
|
+
const toggleMute = useCallback10(async () => {
|
|
3658
3941
|
try {
|
|
3659
3942
|
await localParticipant.setMicrophoneEnabled(isMuted);
|
|
3660
3943
|
} catch (error) {
|
|
3661
3944
|
console.error("Failed to toggle microphone:", error);
|
|
3662
3945
|
}
|
|
3663
3946
|
}, [localParticipant, isMuted]);
|
|
3664
|
-
const toggleScreenShare =
|
|
3947
|
+
const toggleScreenShare = useCallback10(async () => {
|
|
3665
3948
|
try {
|
|
3666
3949
|
await localParticipant.setScreenShareEnabled(!isScreenSharing, SCREEN_SHARE_OPTIONS);
|
|
3667
3950
|
} catch (error) {
|
|
@@ -3672,13 +3955,13 @@ function useMediaControls() {
|
|
|
3672
3955
|
}
|
|
3673
3956
|
|
|
3674
3957
|
// src/hooks/useMicLevel.ts
|
|
3675
|
-
import { useLocalParticipant as
|
|
3958
|
+
import { useLocalParticipant as useLocalParticipant6 } from "@livekit/components-react/hooks";
|
|
3676
3959
|
var MIC_BARS = 5;
|
|
3677
3960
|
var IDLE_BAR_HEIGHT_PX = 5;
|
|
3678
3961
|
var MAX_BAR_GROWTH_PX = 17;
|
|
3679
3962
|
var MIC_NOISE_GATE = 0.15;
|
|
3680
3963
|
function useMicLevel(enabled) {
|
|
3681
|
-
const { microphoneTrack } =
|
|
3964
|
+
const { microphoneTrack } = useLocalParticipant6();
|
|
3682
3965
|
const mediaStreamTrack = microphoneTrack?.track?.mediaStreamTrack;
|
|
3683
3966
|
return useAudioLevelBars(enabled ? mediaStreamTrack : undefined, {
|
|
3684
3967
|
barCount: MIC_BARS,
|
|
@@ -3688,92 +3971,6 @@ function useMicLevel(enabled) {
|
|
|
3688
3971
|
});
|
|
3689
3972
|
}
|
|
3690
3973
|
|
|
3691
|
-
// src/hooks/usePhaseUpdates.ts
|
|
3692
|
-
import { useCallback as useCallback10, useContext as useContext5, useEffect as useEffect16 } from "react";
|
|
3693
|
-
function parsePhases(json) {
|
|
3694
|
-
try {
|
|
3695
|
-
const data = JSON.parse(json);
|
|
3696
|
-
if (data.type === "phase_update" && Array.isArray(data.phases)) {
|
|
3697
|
-
return data.phases;
|
|
3698
|
-
}
|
|
3699
|
-
} catch {}
|
|
3700
|
-
return null;
|
|
3701
|
-
}
|
|
3702
|
-
function usePhaseUpdates() {
|
|
3703
|
-
const parse = useCallback10(parsePhases, []);
|
|
3704
|
-
const livePhases = useAgentState("phases", parse, []);
|
|
3705
|
-
const ctx = useContext5(LiveAgentContext);
|
|
3706
|
-
useEffect16(() => {
|
|
3707
|
-
if (livePhases.length > 0)
|
|
3708
|
-
ctx?.setPhasesSnapshot(livePhases);
|
|
3709
|
-
}, [livePhases, ctx?.setPhasesSnapshot]);
|
|
3710
|
-
const phases = livePhases.length > 0 ? livePhases : ctx?.phasesSnapshot ?? [];
|
|
3711
|
-
return { phases };
|
|
3712
|
-
}
|
|
3713
|
-
|
|
3714
|
-
// src/hooks/useSessionHold.ts
|
|
3715
|
-
import { useLocalParticipant as useLocalParticipant6 } from "@livekit/components-react/hooks";
|
|
3716
|
-
import { useCallback as useCallback11, useEffect as useEffect17, useState as useState11 } from "react";
|
|
3717
|
-
var textEncoder4 = new TextEncoder;
|
|
3718
|
-
var FALLBACK_PAUSE_TIMEOUT_SECONDS = 120;
|
|
3719
|
-
function useSessionHold({
|
|
3720
|
-
pauseSession,
|
|
3721
|
-
pauseTimeoutSeconds
|
|
3722
|
-
}) {
|
|
3723
|
-
const { localParticipant } = useLocalParticipant6();
|
|
3724
|
-
const timeoutSeconds = pauseTimeoutSeconds ?? FALLBACK_PAUSE_TIMEOUT_SECONDS;
|
|
3725
|
-
const [isHeld, setIsHeld] = useState11(false);
|
|
3726
|
-
const [countdown, setCountdown] = useState11(timeoutSeconds);
|
|
3727
|
-
const publish = useCallback11(async (type) => {
|
|
3728
|
-
await localParticipant.publishData(textEncoder4.encode(JSON.stringify({ type })), {
|
|
3729
|
-
reliable: true,
|
|
3730
|
-
topic: SESSION_HOLD_TOPIC
|
|
3731
|
-
});
|
|
3732
|
-
}, [localParticipant]);
|
|
3733
|
-
const hold = useCallback11(async () => {
|
|
3734
|
-
try {
|
|
3735
|
-
await localParticipant.setMicrophoneEnabled(false);
|
|
3736
|
-
await publish("pause");
|
|
3737
|
-
setIsHeld(true);
|
|
3738
|
-
} catch (error) {
|
|
3739
|
-
console.error("Failed to hold session:", error);
|
|
3740
|
-
}
|
|
3741
|
-
}, [localParticipant, publish]);
|
|
3742
|
-
const release = useCallback11(async () => {
|
|
3743
|
-
try {
|
|
3744
|
-
await localParticipant.setMicrophoneEnabled(true);
|
|
3745
|
-
await publish("resume");
|
|
3746
|
-
setIsHeld(false);
|
|
3747
|
-
} catch (error) {
|
|
3748
|
-
console.error("Failed to release session:", error);
|
|
3749
|
-
}
|
|
3750
|
-
}, [localParticipant, publish]);
|
|
3751
|
-
useEffect17(() => {
|
|
3752
|
-
if (!isHeld) {
|
|
3753
|
-
setCountdown(timeoutSeconds);
|
|
3754
|
-
return;
|
|
3755
|
-
}
|
|
3756
|
-
const id = setInterval(() => {
|
|
3757
|
-
setCountdown((seconds) => Math.max(0, seconds - 1));
|
|
3758
|
-
}, 1000);
|
|
3759
|
-
return () => clearInterval(id);
|
|
3760
|
-
}, [isHeld, timeoutSeconds]);
|
|
3761
|
-
useEffect17(() => {
|
|
3762
|
-
if (isHeld && countdown === 0) {
|
|
3763
|
-
setIsHeld(false);
|
|
3764
|
-
pauseSession();
|
|
3765
|
-
}
|
|
3766
|
-
}, [isHeld, countdown, pauseSession]);
|
|
3767
|
-
const toggle = useCallback11(() => {
|
|
3768
|
-
if (isHeld) {
|
|
3769
|
-
release();
|
|
3770
|
-
} else {
|
|
3771
|
-
hold();
|
|
3772
|
-
}
|
|
3773
|
-
}, [isHeld, hold, release]);
|
|
3774
|
-
return { isHeld, countdown, toggle };
|
|
3775
|
-
}
|
|
3776
|
-
|
|
3777
3974
|
// src/components/PausedCountdown.tsx
|
|
3778
3975
|
import { jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3779
3976
|
function PausedCountdown({ secondsRemaining }) {
|
|
@@ -3798,10 +3995,10 @@ function PausedCountdown({ secondsRemaining }) {
|
|
|
3798
3995
|
}
|
|
3799
3996
|
|
|
3800
3997
|
// src/components/SessionControlBar.tsx
|
|
3801
|
-
import { jsx as
|
|
3998
|
+
import { jsx as jsx6, jsxs as jsxs6, Fragment } from "react/jsx-runtime";
|
|
3802
3999
|
var STANDBY_BAR_WIDTH = 168;
|
|
3803
4000
|
var READY_BAR_WIDTH = 238;
|
|
3804
|
-
var PAUSED_BAR_WIDTH =
|
|
4001
|
+
var PAUSED_BAR_WIDTH = 248;
|
|
3805
4002
|
var TEXT_BAR_WIDTH = 100;
|
|
3806
4003
|
var SCREEN_SHARE_EXTRA_WIDTH = 46;
|
|
3807
4004
|
var ACTION_CONTROL_EXTRA_WIDTH = 46;
|
|
@@ -3836,16 +4033,16 @@ function AgentActivity({
|
|
|
3836
4033
|
className: "skippr:flex skippr:items-center skippr:gap-1.5 skippr:text-bubble",
|
|
3837
4034
|
"aria-label": isActing ? "Agent is acting" : `Agent is ${state}`,
|
|
3838
4035
|
children: [
|
|
3839
|
-
/* @__PURE__ */
|
|
4036
|
+
/* @__PURE__ */ jsx6("span", {
|
|
3840
4037
|
className: "skippr:flex skippr:size-5 skippr:shrink-0 skippr:items-center skippr:justify-center",
|
|
3841
|
-
children: isActing ? /* @__PURE__ */
|
|
4038
|
+
children: isActing ? /* @__PURE__ */ jsx6(MousePointerClick, {
|
|
3842
4039
|
strokeWidth: 2,
|
|
3843
4040
|
className: "skippr:size-5 skippr:[animation:skippr-finger-tap_1.1s_ease-in-out_infinite]"
|
|
3844
4041
|
}) : /* @__PURE__ */ jsxs6(Fragment, {
|
|
3845
4042
|
children: [
|
|
3846
|
-
state === "speaking" && /* @__PURE__ */
|
|
4043
|
+
state === "speaking" && /* @__PURE__ */ jsx6("span", {
|
|
3847
4044
|
className: "skippr:flex skippr:h-5 skippr:items-center skippr:gap-[2px]",
|
|
3848
|
-
children: Array.from({ length: AGENT_BARS }).map((_, index2) => /* @__PURE__ */
|
|
4045
|
+
children: Array.from({ length: AGENT_BARS }).map((_, index2) => /* @__PURE__ */ jsx6("span", {
|
|
3849
4046
|
ref: (el) => {
|
|
3850
4047
|
barRefs.current[index2] = el;
|
|
3851
4048
|
},
|
|
@@ -3856,13 +4053,13 @@ function AgentActivity({
|
|
|
3856
4053
|
state === "thinking" && /* @__PURE__ */ jsxs6("span", {
|
|
3857
4054
|
className: "skippr:flex skippr:items-center skippr:gap-[3px]",
|
|
3858
4055
|
children: [
|
|
3859
|
-
/* @__PURE__ */
|
|
4056
|
+
/* @__PURE__ */ jsx6("span", {
|
|
3860
4057
|
className: "skippr:size-[5px] skippr:rounded-full skippr:bg-current skippr:animate-bounce skippr:[animation-delay:0ms]"
|
|
3861
4058
|
}),
|
|
3862
|
-
/* @__PURE__ */
|
|
4059
|
+
/* @__PURE__ */ jsx6("span", {
|
|
3863
4060
|
className: "skippr:size-[5px] skippr:rounded-full skippr:bg-current skippr:animate-bounce skippr:[animation-delay:150ms]"
|
|
3864
4061
|
}),
|
|
3865
|
-
/* @__PURE__ */
|
|
4062
|
+
/* @__PURE__ */ jsx6("span", {
|
|
3866
4063
|
className: "skippr:size-[5px] skippr:rounded-full skippr:bg-current skippr:animate-bounce skippr:[animation-delay:300ms]"
|
|
3867
4064
|
})
|
|
3868
4065
|
]
|
|
@@ -3877,10 +4074,10 @@ function AgentActivity({
|
|
|
3877
4074
|
strokeLinejoin: "round",
|
|
3878
4075
|
"aria-hidden": "true",
|
|
3879
4076
|
children: [
|
|
3880
|
-
/* @__PURE__ */
|
|
4077
|
+
/* @__PURE__ */ jsx6("path", {
|
|
3881
4078
|
d: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"
|
|
3882
4079
|
}),
|
|
3883
|
-
/* @__PURE__ */
|
|
4080
|
+
/* @__PURE__ */ jsx6("circle", {
|
|
3884
4081
|
cx: "12",
|
|
3885
4082
|
cy: "12",
|
|
3886
4083
|
r: "2.5",
|
|
@@ -3893,7 +4090,7 @@ function AgentActivity({
|
|
|
3893
4090
|
]
|
|
3894
4091
|
})
|
|
3895
4092
|
}),
|
|
3896
|
-
/* @__PURE__ */
|
|
4093
|
+
/* @__PURE__ */ jsx6("span", {
|
|
3897
4094
|
className: "skippr:text-[11px] skippr:font-medium skippr:capitalize",
|
|
3898
4095
|
children: label
|
|
3899
4096
|
})
|
|
@@ -3920,11 +4117,9 @@ function SessionControlBar() {
|
|
|
3920
4117
|
const {
|
|
3921
4118
|
textMode,
|
|
3922
4119
|
launcherBottomPx,
|
|
3923
|
-
popsDown,
|
|
3924
4120
|
controlBarRef,
|
|
3925
4121
|
commitLauncherDrop,
|
|
3926
4122
|
panelRef,
|
|
3927
|
-
pauseTimeoutSeconds,
|
|
3928
4123
|
isDragging,
|
|
3929
4124
|
setIsDragging
|
|
3930
4125
|
} = internalCtx;
|
|
@@ -3933,17 +4128,9 @@ function SessionControlBar() {
|
|
|
3933
4128
|
const { wasDraggedRef } = useLauncherDrag(controlBarRef, commitLauncherDrop, panelFollowers, setIsDragging);
|
|
3934
4129
|
const { isMuted, toggleMute, isScreenSharing, toggleScreenShare } = useMediaControls();
|
|
3935
4130
|
const { state, mediaStreamTrack: agentMediaStreamTrack } = useAgentVoiceState();
|
|
3936
|
-
const { phases } = usePhaseUpdates();
|
|
3937
4131
|
const { actionsActive, actionsPaused: actionsPaused2, togglePaused } = useActionControl();
|
|
3938
|
-
const {
|
|
3939
|
-
|
|
3940
|
-
countdown,
|
|
3941
|
-
toggle: togglePause
|
|
3942
|
-
} = useSessionHold({
|
|
3943
|
-
pauseSession,
|
|
3944
|
-
pauseTimeoutSeconds
|
|
3945
|
-
});
|
|
3946
|
-
useEffect18(() => {
|
|
4132
|
+
const { isHeld, countdown, toggle: togglePause } = useSessionHoldContext();
|
|
4133
|
+
useEffect19(() => {
|
|
3947
4134
|
if (isHeld)
|
|
3948
4135
|
minimizePanel();
|
|
3949
4136
|
}, [isHeld, minimizePanel]);
|
|
@@ -3964,18 +4151,6 @@ function SessionControlBar() {
|
|
|
3964
4151
|
}
|
|
3965
4152
|
}
|
|
3966
4153
|
const agendaModule = activeModule && activeModule.mode !== AGENT_MODE.AlwaysOn && activeModule.totalPhases > 0 ? activeModule : null;
|
|
3967
|
-
const agendaProgress = phases.length > 0 ? {
|
|
3968
|
-
completed: phases.filter((phase) => phase.status === "completed").length,
|
|
3969
|
-
total: phases.length
|
|
3970
|
-
} : agendaModule ? {
|
|
3971
|
-
completed: agendaModule.currentSession?.currentPhaseIndex ?? 0,
|
|
3972
|
-
total: agendaModule.totalPhases
|
|
3973
|
-
} : null;
|
|
3974
|
-
const currentPhaseName = phases.find((phase) => phase.status === "active")?.name ?? phases.find((phase) => phase.status === "pending")?.name;
|
|
3975
|
-
const openAgenda = () => {
|
|
3976
|
-
setSidebarTab("agenda");
|
|
3977
|
-
expandPanel();
|
|
3978
|
-
};
|
|
3979
4154
|
const togglePanel = () => {
|
|
3980
4155
|
if (isPanelOpen) {
|
|
3981
4156
|
minimizePanel();
|
|
@@ -3989,21 +4164,20 @@ function SessionControlBar() {
|
|
|
3989
4164
|
return;
|
|
3990
4165
|
action();
|
|
3991
4166
|
};
|
|
4167
|
+
const panelToggleButton = /* @__PURE__ */ jsx6("button", {
|
|
4168
|
+
type: "button",
|
|
4169
|
+
onClick: ifNotDragged(togglePanel),
|
|
4170
|
+
"aria-label": isPanelOpen ? "Close panel" : agendaModule && !textMode ? "Open agenda" : "Open chat",
|
|
4171
|
+
className: cn(SQUARE_BUTTON, "skippr:text-neutral-700", textMode ? "skippr:hover:bg-neutral-100" : "skippr:bg-neutral-100 skippr:hover:bg-neutral-200"),
|
|
4172
|
+
children: /* @__PURE__ */ jsx6(MessageSquare, {
|
|
4173
|
+
className: "skippr:size-5"
|
|
4174
|
+
})
|
|
4175
|
+
});
|
|
3992
4176
|
return /* @__PURE__ */ jsxs6("div", {
|
|
3993
4177
|
ref: controlBarRef,
|
|
3994
4178
|
style: { bottom: launcherBottomPx },
|
|
3995
4179
|
className: cn("skippr:fixed skippr:z-[9999] skippr:touch-none skippr:cursor-grab", position === "right" ? "skippr:right-3" : "skippr:left-3"),
|
|
3996
4180
|
children: [
|
|
3997
|
-
!isPanelOpen && agendaModule && agendaProgress && /* @__PURE__ */ jsx5("div", {
|
|
3998
|
-
className: cn("skippr:absolute", popsDown ? "skippr:top-full skippr:mt-3" : "skippr:bottom-full skippr:mb-3", isReady ? position === "right" ? "skippr:right-7" : "skippr:left-7" : position === "right" ? "skippr:right-0" : "skippr:left-0"),
|
|
3999
|
-
children: /* @__PURE__ */ jsx5(ModulePill, {
|
|
4000
|
-
module: agendaModule,
|
|
4001
|
-
onSelect: ifNotDragged(openAgenda),
|
|
4002
|
-
progress: agendaProgress,
|
|
4003
|
-
label: currentPhaseName ?? agendaModule.name,
|
|
4004
|
-
isLive: true
|
|
4005
|
-
})
|
|
4006
|
-
}),
|
|
4007
4181
|
/* @__PURE__ */ jsxs6("div", {
|
|
4008
4182
|
style: { width: barWidth },
|
|
4009
4183
|
className: cn("skippr:group skippr:relative skippr:flex skippr:h-[54px] skippr:items-center skippr:justify-center skippr:gap-2", "skippr:rounded-[20px] skippr:bg-white skippr:p-2", "skippr:shadow-[0_10px_32px_rgba(0,0,0,0.18)] skippr:ring-1 skippr:ring-black/5", "skippr:transition-[width,margin] skippr:duration-300 skippr:ease-out", "skippr:[animation:skippr-toolset-pop_440ms_cubic-bezier(0.22,1,0.36,1)]", isReady && (position === "right" ? "skippr:mr-7" : "skippr:ml-7")),
|
|
@@ -4014,18 +4188,18 @@ function SessionControlBar() {
|
|
|
4014
4188
|
/* @__PURE__ */ jsxs6("span", {
|
|
4015
4189
|
className: "skippr:flex skippr:items-center skippr:gap-[3px]",
|
|
4016
4190
|
children: [
|
|
4017
|
-
/* @__PURE__ */
|
|
4191
|
+
/* @__PURE__ */ jsx6("span", {
|
|
4018
4192
|
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-bubble skippr:animate-bounce skippr:[animation-delay:0ms]"
|
|
4019
4193
|
}),
|
|
4020
|
-
/* @__PURE__ */
|
|
4194
|
+
/* @__PURE__ */ jsx6("span", {
|
|
4021
4195
|
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-bubble skippr:animate-bounce skippr:[animation-delay:150ms]"
|
|
4022
4196
|
}),
|
|
4023
|
-
/* @__PURE__ */
|
|
4197
|
+
/* @__PURE__ */ jsx6("span", {
|
|
4024
4198
|
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-bubble skippr:animate-bounce skippr:[animation-delay:300ms]"
|
|
4025
4199
|
})
|
|
4026
4200
|
]
|
|
4027
4201
|
}),
|
|
4028
|
-
/* @__PURE__ */
|
|
4202
|
+
/* @__PURE__ */ jsx6("span", {
|
|
4029
4203
|
children: "Standing by…"
|
|
4030
4204
|
})
|
|
4031
4205
|
]
|
|
@@ -4033,32 +4207,37 @@ function SessionControlBar() {
|
|
|
4033
4207
|
isReady && /* @__PURE__ */ jsxs6("div", {
|
|
4034
4208
|
className: cn("skippr:flex skippr:items-center skippr:gap-2 skippr:[animation:skippr-stage-fade_240ms_ease-out]", isHeld && "skippr:w-full skippr:justify-start"),
|
|
4035
4209
|
children: [
|
|
4036
|
-
/* @__PURE__ */
|
|
4210
|
+
/* @__PURE__ */ jsx6("button", {
|
|
4037
4211
|
type: "button",
|
|
4038
4212
|
onClick: ifNotDragged(togglePause),
|
|
4039
4213
|
"aria-label": isHeld ? "Resume" : "Pause",
|
|
4040
4214
|
title: isHeld ? "Resume" : "Pause",
|
|
4041
4215
|
className: cn(SQUARE_BUTTON, isHeld ? "skippr:bg-bubble skippr:text-white skippr:hover:bg-[#3a384b]" : "skippr:bg-neutral-100 skippr:text-neutral-700 skippr:hover:bg-neutral-200"),
|
|
4042
|
-
children: isHeld ? /* @__PURE__ */
|
|
4216
|
+
children: isHeld ? /* @__PURE__ */ jsx6(Play, {
|
|
4043
4217
|
className: "skippr:size-5",
|
|
4044
4218
|
fill: "currentColor"
|
|
4045
|
-
}) : /* @__PURE__ */
|
|
4219
|
+
}) : /* @__PURE__ */ jsx6(Pause, {
|
|
4046
4220
|
className: "skippr:size-5",
|
|
4047
4221
|
fill: "currentColor"
|
|
4048
4222
|
})
|
|
4049
4223
|
}),
|
|
4050
|
-
isHeld ? /* @__PURE__ */
|
|
4051
|
-
|
|
4224
|
+
isHeld ? /* @__PURE__ */ jsxs6(Fragment, {
|
|
4225
|
+
children: [
|
|
4226
|
+
/* @__PURE__ */ jsx6(PausedCountdown, {
|
|
4227
|
+
secondsRemaining: countdown
|
|
4228
|
+
}),
|
|
4229
|
+
panelToggleButton
|
|
4230
|
+
]
|
|
4052
4231
|
}) : /* @__PURE__ */ jsxs6(Fragment, {
|
|
4053
4232
|
children: [
|
|
4054
4233
|
!textMode && /* @__PURE__ */ jsxs6("div", {
|
|
4055
4234
|
className: "skippr:relative skippr:h-[38px]",
|
|
4056
4235
|
style: { width: MIC_REGION_WIDTH },
|
|
4057
4236
|
children: [
|
|
4058
|
-
!isTalking && /* @__PURE__ */
|
|
4237
|
+
!isTalking && /* @__PURE__ */ jsx6("span", {
|
|
4059
4238
|
className: "skippr:absolute skippr:inset-y-0 skippr:right-0 skippr:flex skippr:items-center skippr:justify-center skippr:[animation:skippr-agent-in_200ms_ease-out_240ms_both]",
|
|
4060
4239
|
style: { width: AGENT_ACTIVITY_WIDTH },
|
|
4061
|
-
children: /* @__PURE__ */
|
|
4240
|
+
children: /* @__PURE__ */ jsx6(AgentActivity, {
|
|
4062
4241
|
state,
|
|
4063
4242
|
isActing: showActionControl && !actionsPaused2,
|
|
4064
4243
|
mediaStreamTrack: agentMediaStreamTrack
|
|
@@ -4071,17 +4250,17 @@ function SessionControlBar() {
|
|
|
4071
4250
|
className: cn("skippr:group skippr:absolute skippr:top-0 skippr:left-0 skippr:z-10 skippr:flex skippr:h-[38px] skippr:items-center skippr:gap-2.5 skippr:overflow-hidden skippr:rounded-[12px] skippr:bg-bubble skippr:text-white skippr:cursor-pointer skippr:transition-[width] skippr:duration-300 skippr:ease-out", isTalking ? "skippr:justify-start skippr:pl-3.5" : "skippr:justify-center"),
|
|
4072
4251
|
style: { width: isTalking ? MIC_REGION_WIDTH : MIC_SQUARE_WIDTH },
|
|
4073
4252
|
children: [
|
|
4074
|
-
/* @__PURE__ */
|
|
4253
|
+
/* @__PURE__ */ jsx6("span", {
|
|
4075
4254
|
className: cn("skippr:flex skippr:shrink-0 skippr:items-center skippr:justify-center skippr:transition-colors", isMuted ? "skippr:text-red-400 skippr:group-hover:text-red-300" : "skippr:text-white skippr:group-hover:text-white/80"),
|
|
4076
|
-
children: isMuted ? /* @__PURE__ */
|
|
4255
|
+
children: isMuted ? /* @__PURE__ */ jsx6(MicOff, {
|
|
4077
4256
|
className: "skippr:size-5"
|
|
4078
|
-
}) : /* @__PURE__ */
|
|
4257
|
+
}) : /* @__PURE__ */ jsx6(Mic, {
|
|
4079
4258
|
className: "skippr:size-5"
|
|
4080
4259
|
})
|
|
4081
4260
|
}),
|
|
4082
|
-
/* @__PURE__ */
|
|
4261
|
+
/* @__PURE__ */ jsx6("span", {
|
|
4083
4262
|
className: cn("skippr:h-6 skippr:flex-1 skippr:items-center skippr:justify-center skippr:gap-[3px] skippr:transition-opacity skippr:duration-200", isTalking ? "skippr:flex skippr:opacity-100" : "skippr:hidden"),
|
|
4084
|
-
children: Array.from({ length: MIC_BARS }).map((_, index2) => /* @__PURE__ */
|
|
4263
|
+
children: Array.from({ length: MIC_BARS }).map((_, index2) => /* @__PURE__ */ jsx6("span", {
|
|
4085
4264
|
ref: (el) => {
|
|
4086
4265
|
barRefs.current[index2] = el;
|
|
4087
4266
|
},
|
|
@@ -4093,36 +4272,28 @@ function SessionControlBar() {
|
|
|
4093
4272
|
})
|
|
4094
4273
|
]
|
|
4095
4274
|
}),
|
|
4096
|
-
showScreenShareToggle && /* @__PURE__ */
|
|
4275
|
+
showScreenShareToggle && /* @__PURE__ */ jsx6("button", {
|
|
4097
4276
|
type: "button",
|
|
4098
4277
|
onClick: ifNotDragged(() => void toggleScreenShare()),
|
|
4099
4278
|
"aria-label": isScreenSharing ? "Stop sharing screen" : "Share screen",
|
|
4100
4279
|
className: cn(SQUARE_BUTTON, isScreenSharing ? "skippr:bg-bubble skippr:text-white skippr:hover:bg-[#3a384b]" : "skippr:bg-neutral-100 skippr:text-neutral-700 skippr:hover:bg-neutral-200"),
|
|
4101
|
-
children: isScreenSharing ? /* @__PURE__ */
|
|
4102
|
-
className: "skippr:size-5"
|
|
4103
|
-
}) : /* @__PURE__ */ jsx5(Monitor, {
|
|
4280
|
+
children: isScreenSharing ? /* @__PURE__ */ jsx6(MonitorOff, {
|
|
4104
4281
|
className: "skippr:size-5"
|
|
4105
|
-
})
|
|
4106
|
-
}),
|
|
4107
|
-
/* @__PURE__ */ jsx5("button", {
|
|
4108
|
-
type: "button",
|
|
4109
|
-
onClick: ifNotDragged(togglePanel),
|
|
4110
|
-
"aria-label": isPanelOpen ? "Close panel" : agendaModule && !textMode ? "Open agenda" : "Open chat",
|
|
4111
|
-
className: cn(SQUARE_BUTTON, "skippr:text-neutral-700", textMode ? "skippr:hover:bg-neutral-100" : "skippr:bg-neutral-100 skippr:hover:bg-neutral-200"),
|
|
4112
|
-
children: /* @__PURE__ */ jsx5(MessageSquare, {
|
|
4282
|
+
}) : /* @__PURE__ */ jsx6(Monitor, {
|
|
4113
4283
|
className: "skippr:size-5"
|
|
4114
4284
|
})
|
|
4115
4285
|
}),
|
|
4116
|
-
|
|
4286
|
+
panelToggleButton,
|
|
4287
|
+
showActionControl && /* @__PURE__ */ jsx6("button", {
|
|
4117
4288
|
type: "button",
|
|
4118
4289
|
onClick: ifNotDragged(() => void togglePaused()),
|
|
4119
4290
|
"aria-label": actionsPaused2 ? "Resume actions" : "Stop actions",
|
|
4120
4291
|
title: actionsPaused2 ? "Resume" : "Stop",
|
|
4121
4292
|
className: cn(SQUARE_BUTTON, actionsPaused2 ? "skippr:bg-green-100 skippr:text-green-700 skippr:hover:bg-green-200" : "skippr:bg-red-100 skippr:text-red-600 skippr:hover:bg-red-200"),
|
|
4122
|
-
children: actionsPaused2 ? /* @__PURE__ */
|
|
4293
|
+
children: actionsPaused2 ? /* @__PURE__ */ jsx6(Play, {
|
|
4123
4294
|
className: "skippr:size-5",
|
|
4124
4295
|
fill: "currentColor"
|
|
4125
|
-
}) : /* @__PURE__ */
|
|
4296
|
+
}) : /* @__PURE__ */ jsx6(Square, {
|
|
4126
4297
|
className: "skippr:size-5",
|
|
4127
4298
|
fill: "currentColor"
|
|
4128
4299
|
})
|
|
@@ -4133,7 +4304,7 @@ function SessionControlBar() {
|
|
|
4133
4304
|
}, textMode ? "ready-text" : "ready")
|
|
4134
4305
|
]
|
|
4135
4306
|
}),
|
|
4136
|
-
isReady && !isDragging && /* @__PURE__ */
|
|
4307
|
+
isReady && !isDragging && /* @__PURE__ */ jsx6("button", {
|
|
4137
4308
|
type: "button",
|
|
4138
4309
|
onClick: ifNotDragged(() => void pauseSession()),
|
|
4139
4310
|
disabled: isPausing,
|
|
@@ -4143,7 +4314,7 @@ function SessionControlBar() {
|
|
|
4143
4314
|
children: /* @__PURE__ */ jsxs6("span", {
|
|
4144
4315
|
className: "skippr:relative skippr:flex skippr:size-5 skippr:items-center skippr:justify-center",
|
|
4145
4316
|
children: [
|
|
4146
|
-
/* @__PURE__ */
|
|
4317
|
+
/* @__PURE__ */ jsx6(X, {
|
|
4147
4318
|
className: cn("skippr:size-4 skippr:transition-opacity skippr:duration-200", isPausing && "skippr:opacity-40"),
|
|
4148
4319
|
strokeWidth: 2.5
|
|
4149
4320
|
}),
|
|
@@ -4153,7 +4324,7 @@ function SessionControlBar() {
|
|
|
4153
4324
|
"aria-hidden": "true",
|
|
4154
4325
|
className: "skippr:absolute skippr:inset-0 skippr:size-full skippr:animate-spin skippr:motion-reduce:hidden",
|
|
4155
4326
|
children: [
|
|
4156
|
-
/* @__PURE__ */
|
|
4327
|
+
/* @__PURE__ */ jsx6("circle", {
|
|
4157
4328
|
cx: "12",
|
|
4158
4329
|
cy: "12",
|
|
4159
4330
|
r: "10.5",
|
|
@@ -4161,7 +4332,7 @@ function SessionControlBar() {
|
|
|
4161
4332
|
strokeOpacity: "0.2",
|
|
4162
4333
|
strokeWidth: "1.5"
|
|
4163
4334
|
}),
|
|
4164
|
-
/* @__PURE__ */
|
|
4335
|
+
/* @__PURE__ */ jsx6("circle", {
|
|
4165
4336
|
cx: "12",
|
|
4166
4337
|
cy: "12",
|
|
4167
4338
|
r: "10.5",
|
|
@@ -4180,9 +4351,9 @@ function SessionControlBar() {
|
|
|
4180
4351
|
}
|
|
4181
4352
|
|
|
4182
4353
|
// src/components/ShadowHost.tsx
|
|
4183
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as
|
|
4354
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef11, useState as useState13 } from "react";
|
|
4184
4355
|
import { createPortal } from "react-dom";
|
|
4185
|
-
import { jsx as
|
|
4356
|
+
import { jsx as jsx7, Fragment as Fragment2 } from "react/jsx-runtime";
|
|
4186
4357
|
var PROPERTIES_STYLE_ID = "skippr-tw-properties";
|
|
4187
4358
|
var PROPERTY_RULE = /@property\s+[^{]+\{[^}]*\}/g;
|
|
4188
4359
|
function hoistTailwindProperties(css) {
|
|
@@ -4197,10 +4368,10 @@ function hoistTailwindProperties(css) {
|
|
|
4197
4368
|
return css.replace(PROPERTY_RULE, "");
|
|
4198
4369
|
}
|
|
4199
4370
|
function ShadowHost({ children }) {
|
|
4200
|
-
const hostRef =
|
|
4201
|
-
const [shadowRoot, setShadowRoot] =
|
|
4371
|
+
const hostRef = useRef11(null);
|
|
4372
|
+
const [shadowRoot, setShadowRoot] = useState13(null);
|
|
4202
4373
|
const css = `/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
|
|
4203
|
-
@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-emerald-500:oklch(69.6% .17 162.48);--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-pulse:pulse 2s cubic-bezier(.4,0,.6,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\\:right-7{right:calc(var(--skippr-spacing)*7)}.skippr\\:right-\\[24px\\]{right:24px}.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\\:left-7{left:calc(var(--skippr-spacing)*7)}.skippr\\:left-\\[24px\\]{left:24px}.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\\: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-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-\\[6px\\]{width:6px;height:6px}.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-\\[38px\\]{height:38px}.skippr\\:h-\\[50px\\]{height:50px}.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-\\[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-7{--tw-translate-x:calc(var(--skippr-spacing)*-7);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-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);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-pulse{animation:var(--skippr-animate-pulse)}.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-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-\\[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-tl-md{border-top-left-radius:.5rem}.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-emerald-500{background-color:var(--skippr-color-emerald-500)}.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\\.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\\: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_6px_22px_rgba\\(0\\,0\\,0\\,0\\.3\\)\\]{--tw-shadow:-6px 6px 22px var(--tw-shadow-color,#0000004d);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\\: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\\:scale-110:hover{--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x)var(--tw-scale-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\\:motion-reduce\\:animate-none{animation: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 pulse{50%{opacity:.5}}@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}}`;
|
|
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}}`;
|
|
4204
4375
|
useLayoutEffect2(() => {
|
|
4205
4376
|
const host = hostRef.current;
|
|
4206
4377
|
if (!host || !css)
|
|
@@ -4215,24 +4386,24 @@ function ShadowHost({ children }) {
|
|
|
4215
4386
|
setShadowRoot(root);
|
|
4216
4387
|
}, [css]);
|
|
4217
4388
|
if (!css)
|
|
4218
|
-
return /* @__PURE__ */
|
|
4389
|
+
return /* @__PURE__ */ jsx7(Fragment2, {
|
|
4219
4390
|
children
|
|
4220
4391
|
});
|
|
4221
|
-
return /* @__PURE__ */
|
|
4392
|
+
return /* @__PURE__ */ jsx7("div", {
|
|
4222
4393
|
ref: hostRef,
|
|
4223
4394
|
children: shadowRoot && createPortal(children, shadowRoot)
|
|
4224
4395
|
});
|
|
4225
4396
|
}
|
|
4226
4397
|
|
|
4227
4398
|
// src/components/Sidebar.tsx
|
|
4228
|
-
import { useContext as
|
|
4399
|
+
import { useContext as useContext11, useEffect as useEffect26 } from "react";
|
|
4229
4400
|
|
|
4230
4401
|
// src/hooks/useCombinedMessages.ts
|
|
4231
|
-
import { useContext as useContext7, useMemo as
|
|
4402
|
+
import { useContext as useContext7, useMemo as useMemo6 } from "react";
|
|
4232
4403
|
|
|
4233
4404
|
// src/hooks/useChatMessages.ts
|
|
4234
4405
|
import { useChat, useLocalParticipant as useLocalParticipant7 } from "@livekit/components-react/hooks";
|
|
4235
|
-
import { useMemo as
|
|
4406
|
+
import { useMemo as useMemo4 } from "react";
|
|
4236
4407
|
|
|
4237
4408
|
// src/lib/filterSystemMessages.ts
|
|
4238
4409
|
var SYSTEM_MESSAGE_PATTERN = /^\[\w+\]$/;
|
|
@@ -4245,7 +4416,7 @@ function useChatMessages() {
|
|
|
4245
4416
|
const { chatMessages: rawMessages, send, isSending } = useChat();
|
|
4246
4417
|
const { localParticipant } = useLocalParticipant7();
|
|
4247
4418
|
const localIdentity = localParticipant.identity;
|
|
4248
|
-
const chatMessages =
|
|
4419
|
+
const chatMessages = useMemo4(() => {
|
|
4249
4420
|
const sortedMessages = rawMessages.map((msg) => ({
|
|
4250
4421
|
id: msg.id,
|
|
4251
4422
|
role: msg.from?.identity === localIdentity ? "user" : "assistant",
|
|
@@ -4260,12 +4431,12 @@ function useChatMessages() {
|
|
|
4260
4431
|
|
|
4261
4432
|
// src/hooks/useStreamingTranscript.ts
|
|
4262
4433
|
import { useLocalParticipant as useLocalParticipant8, useTranscriptions } from "@livekit/components-react/hooks";
|
|
4263
|
-
import { useMemo as
|
|
4434
|
+
import { useMemo as useMemo5 } from "react";
|
|
4264
4435
|
function useStreamingTranscript() {
|
|
4265
4436
|
const transcriptions = useTranscriptions();
|
|
4266
4437
|
const { localParticipant } = useLocalParticipant8();
|
|
4267
4438
|
const localIdentity = localParticipant.identity;
|
|
4268
|
-
const transcriptMessages =
|
|
4439
|
+
const transcriptMessages = useMemo5(() => filterSystemMessages(transcriptions.filter((stream) => stream.text.trim().length > 0).map((stream) => ({
|
|
4269
4440
|
id: stream.streamInfo.id,
|
|
4270
4441
|
role: stream.participantInfo.identity === localIdentity ? "user" : "assistant",
|
|
4271
4442
|
content: stream.text,
|
|
@@ -4297,14 +4468,14 @@ function useCombinedMessages() {
|
|
|
4297
4468
|
const { chatMessages, sendChatMessage, isSendingChat } = useChatMessages();
|
|
4298
4469
|
const { state: agentState } = useAgentVoiceState();
|
|
4299
4470
|
const historyMessages = useContext7(LiveAgentContext)?.historyMessages ?? [];
|
|
4300
|
-
const liveMessages =
|
|
4471
|
+
const liveMessages = useMemo6(() => {
|
|
4301
4472
|
if (chatMessages.length === 0)
|
|
4302
4473
|
return transcriptMessages;
|
|
4303
4474
|
if (transcriptMessages.length === 0)
|
|
4304
4475
|
return chatMessages;
|
|
4305
4476
|
return mergeChatsIntoTranscripts(transcriptMessages, chatMessages);
|
|
4306
4477
|
}, [transcriptMessages, chatMessages]);
|
|
4307
|
-
const allMessages =
|
|
4478
|
+
const allMessages = useMemo6(() => {
|
|
4308
4479
|
if (historyMessages.length === 0)
|
|
4309
4480
|
return liveMessages;
|
|
4310
4481
|
const seenIds = new Set(liveMessages.map((message) => message.id));
|
|
@@ -4313,8 +4484,31 @@ function useCombinedMessages() {
|
|
|
4313
4484
|
return { allMessages, agentState, sendChatMessage, isSendingChat };
|
|
4314
4485
|
}
|
|
4315
4486
|
|
|
4487
|
+
// src/hooks/usePhaseUpdates.ts
|
|
4488
|
+
import { useCallback as useCallback11, useContext as useContext8, useEffect as useEffect20 } from "react";
|
|
4489
|
+
function parsePhases(json) {
|
|
4490
|
+
try {
|
|
4491
|
+
const data = JSON.parse(json);
|
|
4492
|
+
if (data.type === "phase_update" && Array.isArray(data.phases)) {
|
|
4493
|
+
return data.phases;
|
|
4494
|
+
}
|
|
4495
|
+
} catch {}
|
|
4496
|
+
return null;
|
|
4497
|
+
}
|
|
4498
|
+
function usePhaseUpdates() {
|
|
4499
|
+
const parse = useCallback11(parsePhases, []);
|
|
4500
|
+
const livePhases = useAgentState("phases", parse, []);
|
|
4501
|
+
const ctx = useContext8(LiveAgentContext);
|
|
4502
|
+
useEffect20(() => {
|
|
4503
|
+
if (livePhases.length > 0)
|
|
4504
|
+
ctx?.setPhasesSnapshot(livePhases);
|
|
4505
|
+
}, [livePhases, ctx?.setPhasesSnapshot]);
|
|
4506
|
+
const phases = livePhases.length > 0 ? livePhases : ctx?.phasesSnapshot ?? [];
|
|
4507
|
+
return { phases };
|
|
4508
|
+
}
|
|
4509
|
+
|
|
4316
4510
|
// src/hooks/useSessionRemaining.ts
|
|
4317
|
-
import { useEffect as
|
|
4511
|
+
import { useEffect as useEffect21, useRef as useRef12, useState as useState14 } from "react";
|
|
4318
4512
|
|
|
4319
4513
|
// src/lib/format.ts
|
|
4320
4514
|
function formatTime(seconds) {
|
|
@@ -4330,9 +4524,9 @@ function parseNumber(s) {
|
|
|
4330
4524
|
// src/hooks/useSessionRemaining.ts
|
|
4331
4525
|
function useSessionRemaining() {
|
|
4332
4526
|
const maxCallDuration = useAgentState("maxCallDuration", parseNumber, null);
|
|
4333
|
-
const endTimeRef =
|
|
4334
|
-
const [remaining, setRemaining] =
|
|
4335
|
-
|
|
4527
|
+
const endTimeRef = useRef12(null);
|
|
4528
|
+
const [remaining, setRemaining] = useState14(null);
|
|
4529
|
+
useEffect21(() => {
|
|
4336
4530
|
if (maxCallDuration === null || endTimeRef.current !== null)
|
|
4337
4531
|
return;
|
|
4338
4532
|
const endTime = Date.now() + maxCallDuration * 1000;
|
|
@@ -4349,13 +4543,13 @@ function useSessionRemaining() {
|
|
|
4349
4543
|
}
|
|
4350
4544
|
|
|
4351
4545
|
// src/components/ChatHeader.tsx
|
|
4352
|
-
import { useContext as
|
|
4546
|
+
import { useContext as useContext10, useRef as useRef14 } from "react";
|
|
4353
4547
|
|
|
4354
4548
|
// src/hooks/useElapsedSeconds.ts
|
|
4355
|
-
import { useEffect as
|
|
4549
|
+
import { useEffect as useEffect22, useState as useState15 } from "react";
|
|
4356
4550
|
function useElapsedSeconds(isRunning) {
|
|
4357
|
-
const [elapsed, setElapsed] =
|
|
4358
|
-
|
|
4551
|
+
const [elapsed, setElapsed] = useState15(0);
|
|
4552
|
+
useEffect22(() => {
|
|
4359
4553
|
if (!isRunning) {
|
|
4360
4554
|
setElapsed(0);
|
|
4361
4555
|
return;
|
|
@@ -4372,16 +4566,16 @@ function useElapsedSeconds(isRunning) {
|
|
|
4372
4566
|
|
|
4373
4567
|
// src/hooks/useTextMode.ts
|
|
4374
4568
|
import { useLocalParticipant as useLocalParticipant9 } from "@livekit/components-react/hooks";
|
|
4375
|
-
import { useCallback as useCallback12, useContext as
|
|
4569
|
+
import { useCallback as useCallback12, useContext as useContext9, useRef as useRef13 } from "react";
|
|
4376
4570
|
var textEncoder5 = new TextEncoder;
|
|
4377
4571
|
function useTextMode() {
|
|
4378
|
-
const ctx =
|
|
4572
|
+
const ctx = useContext9(LiveAgentContext);
|
|
4379
4573
|
if (!ctx) {
|
|
4380
4574
|
throw new Error("useTextMode must be used within a <LiveAgent> provider");
|
|
4381
4575
|
}
|
|
4382
4576
|
const { textMode, setTextModeState, sidebarTab, setSidebarTab } = ctx;
|
|
4383
4577
|
const { localParticipant } = useLocalParticipant9();
|
|
4384
|
-
const confirmedTextModeRef =
|
|
4578
|
+
const confirmedTextModeRef = useRef13(false);
|
|
4385
4579
|
const toggleTextMode = useCallback12(async () => {
|
|
4386
4580
|
const next = !textMode;
|
|
4387
4581
|
setTextModeState(next);
|
|
@@ -4404,9 +4598,9 @@ function useTextMode() {
|
|
|
4404
4598
|
}
|
|
4405
4599
|
|
|
4406
4600
|
// src/components/ChatHeader.tsx
|
|
4407
|
-
import { jsx as
|
|
4601
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4408
4602
|
function ChatHeader() {
|
|
4409
|
-
const ctx =
|
|
4603
|
+
const ctx = useContext10(LiveAgentContext);
|
|
4410
4604
|
if (!ctx) {
|
|
4411
4605
|
throw new Error("ChatHeader must be used within a <LiveAgent> provider");
|
|
4412
4606
|
}
|
|
@@ -4422,7 +4616,7 @@ function ChatHeader() {
|
|
|
4422
4616
|
setIsDragging
|
|
4423
4617
|
} = ctx;
|
|
4424
4618
|
const elapsed = useElapsedSeconds(isConnected);
|
|
4425
|
-
const headerRef =
|
|
4619
|
+
const headerRef = useRef14(null);
|
|
4426
4620
|
const followsPanel = variant === "floating" && isPanelOpen;
|
|
4427
4621
|
const dragFollowers = followsPanel ? [panelRef, controlBarRef] : null;
|
|
4428
4622
|
const { wasDraggedRef } = useLauncherDrag(headerRef, commitLauncherDrop, dragFollowers, setIsDragging);
|
|
@@ -4433,26 +4627,26 @@ function ChatHeader() {
|
|
|
4433
4627
|
/* @__PURE__ */ jsxs7("div", {
|
|
4434
4628
|
className: "skippr:flex skippr:items-center skippr:gap-3",
|
|
4435
4629
|
children: [
|
|
4436
|
-
isConnected && /* @__PURE__ */
|
|
4630
|
+
isConnected && /* @__PURE__ */ jsx8(HeaderModeToggle, {}),
|
|
4437
4631
|
isConnected && /* @__PURE__ */ jsxs7("div", {
|
|
4438
4632
|
className: "skippr:flex skippr:items-center skippr:gap-1.5 skippr:rounded-full skippr:bg-primary-foreground/20 skippr:px-2.5 skippr:py-1",
|
|
4439
4633
|
children: [
|
|
4440
4634
|
/* @__PURE__ */ jsxs7("span", {
|
|
4441
4635
|
className: "skippr:relative skippr:flex skippr:size-1.5",
|
|
4442
4636
|
children: [
|
|
4443
|
-
/* @__PURE__ */
|
|
4637
|
+
/* @__PURE__ */ jsx8("span", {
|
|
4444
4638
|
className: "skippr:absolute skippr:inline-flex skippr:h-full skippr:w-full skippr:animate-ping skippr:rounded-full skippr:bg-red-400 skippr:opacity-75"
|
|
4445
4639
|
}),
|
|
4446
|
-
/* @__PURE__ */
|
|
4640
|
+
/* @__PURE__ */ jsx8("span", {
|
|
4447
4641
|
className: "skippr:relative skippr:inline-flex skippr:size-1.5 skippr:rounded-full skippr:bg-red-400"
|
|
4448
4642
|
})
|
|
4449
4643
|
]
|
|
4450
4644
|
}),
|
|
4451
|
-
/* @__PURE__ */
|
|
4645
|
+
/* @__PURE__ */ jsx8("span", {
|
|
4452
4646
|
className: "skippr:text-[10px] skippr:font-medium skippr:text-primary-foreground",
|
|
4453
4647
|
children: "REC"
|
|
4454
4648
|
}),
|
|
4455
|
-
/* @__PURE__ */
|
|
4649
|
+
/* @__PURE__ */ jsx8("span", {
|
|
4456
4650
|
className: "skippr:text-[10px] skippr:font-mono skippr:text-primary-foreground",
|
|
4457
4651
|
children: formatTime(elapsed)
|
|
4458
4652
|
})
|
|
@@ -4460,7 +4654,7 @@ function ChatHeader() {
|
|
|
4460
4654
|
})
|
|
4461
4655
|
]
|
|
4462
4656
|
}),
|
|
4463
|
-
minimizable && /* @__PURE__ */
|
|
4657
|
+
minimizable && /* @__PURE__ */ jsx8("button", {
|
|
4464
4658
|
type: "button",
|
|
4465
4659
|
onClick: () => {
|
|
4466
4660
|
if (!wasDraggedRef.current)
|
|
@@ -4469,7 +4663,7 @@ function ChatHeader() {
|
|
|
4469
4663
|
"aria-label": "Close",
|
|
4470
4664
|
title: "Close",
|
|
4471
4665
|
className: "skippr:flex skippr:h-8 skippr:w-8 skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:rounded-lg skippr:text-primary-foreground/70 skippr:transition-colors skippr:hover:bg-white/10 skippr:hover:text-primary-foreground skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-brand",
|
|
4472
|
-
children: /* @__PURE__ */
|
|
4666
|
+
children: /* @__PURE__ */ jsx8(X, {
|
|
4473
4667
|
className: "skippr:h-4 skippr:w-4"
|
|
4474
4668
|
})
|
|
4475
4669
|
})
|
|
@@ -4478,28 +4672,32 @@ function ChatHeader() {
|
|
|
4478
4672
|
}
|
|
4479
4673
|
function HeaderModeToggle() {
|
|
4480
4674
|
const { textMode, toggleTextMode } = useTextMode();
|
|
4675
|
+
const { isHeld } = useSessionHoldContext();
|
|
4481
4676
|
return /* @__PURE__ */ jsxs7("fieldset", {
|
|
4482
4677
|
"aria-label": "Response mode",
|
|
4483
|
-
|
|
4678
|
+
disabled: isHeld,
|
|
4679
|
+
className: "skippr:flex skippr:items-center skippr:gap-0.5 skippr:rounded-lg skippr:bg-white/15 skippr:p-0.5 skippr:text-xs skippr:font-medium skippr:ring-1 skippr:ring-white/30 skippr:disabled:opacity-50",
|
|
4484
4680
|
children: [
|
|
4485
|
-
/* @__PURE__ */
|
|
4681
|
+
/* @__PURE__ */ jsx8("button", {
|
|
4486
4682
|
type: "button",
|
|
4487
4683
|
"aria-pressed": !textMode,
|
|
4684
|
+
disabled: isHeld,
|
|
4488
4685
|
onClick: () => {
|
|
4489
4686
|
if (textMode)
|
|
4490
4687
|
toggleTextMode();
|
|
4491
4688
|
},
|
|
4492
|
-
className: cn("skippr:
|
|
4689
|
+
className: cn("skippr:rounded-md skippr:px-2.5 skippr:py-1 skippr:transition-colors skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-brand skippr:disabled:cursor-not-allowed", isHeld ? "skippr:cursor-not-allowed" : "skippr:cursor-pointer", textMode ? "skippr:font-semibold skippr:text-primary-foreground" : "skippr:bg-white skippr:text-primary skippr:shadow-sm"),
|
|
4493
4690
|
children: "Voice"
|
|
4494
4691
|
}),
|
|
4495
|
-
/* @__PURE__ */
|
|
4692
|
+
/* @__PURE__ */ jsx8("button", {
|
|
4496
4693
|
type: "button",
|
|
4497
4694
|
"aria-pressed": textMode,
|
|
4695
|
+
disabled: isHeld,
|
|
4498
4696
|
onClick: () => {
|
|
4499
4697
|
if (!textMode)
|
|
4500
4698
|
toggleTextMode();
|
|
4501
4699
|
},
|
|
4502
|
-
className: cn("skippr:
|
|
4700
|
+
className: cn("skippr:rounded-md skippr:px-2.5 skippr:py-1 skippr:transition-colors skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-brand skippr:disabled:cursor-not-allowed", isHeld ? "skippr:cursor-not-allowed" : "skippr:cursor-pointer", textMode ? "skippr:bg-white skippr:text-primary skippr:shadow-sm" : "skippr:font-semibold skippr:text-primary-foreground"),
|
|
4503
4701
|
children: "Text"
|
|
4504
4702
|
})
|
|
4505
4703
|
]
|
|
@@ -4507,7 +4705,7 @@ function HeaderModeToggle() {
|
|
|
4507
4705
|
}
|
|
4508
4706
|
|
|
4509
4707
|
// src/components/LoadingDots.tsx
|
|
4510
|
-
import { jsx as
|
|
4708
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4511
4709
|
function LoadingDots({ label }) {
|
|
4512
4710
|
return /* @__PURE__ */ jsxs8("div", {
|
|
4513
4711
|
className: "skippr:flex skippr:items-center skippr:gap-2 skippr:py-4",
|
|
@@ -4515,18 +4713,18 @@ function LoadingDots({ label }) {
|
|
|
4515
4713
|
/* @__PURE__ */ jsxs8("div", {
|
|
4516
4714
|
className: "skippr:flex skippr:gap-1",
|
|
4517
4715
|
children: [
|
|
4518
|
-
/* @__PURE__ */
|
|
4716
|
+
/* @__PURE__ */ jsx9("span", {
|
|
4519
4717
|
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-muted-foreground/40 skippr:animate-bounce skippr:[animation-delay:0ms]"
|
|
4520
4718
|
}),
|
|
4521
|
-
/* @__PURE__ */
|
|
4719
|
+
/* @__PURE__ */ jsx9("span", {
|
|
4522
4720
|
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-muted-foreground/40 skippr:animate-bounce skippr:[animation-delay:150ms]"
|
|
4523
4721
|
}),
|
|
4524
|
-
/* @__PURE__ */
|
|
4722
|
+
/* @__PURE__ */ jsx9("span", {
|
|
4525
4723
|
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-muted-foreground/40 skippr:animate-bounce skippr:[animation-delay:300ms]"
|
|
4526
4724
|
})
|
|
4527
4725
|
]
|
|
4528
4726
|
}),
|
|
4529
|
-
/* @__PURE__ */
|
|
4727
|
+
/* @__PURE__ */ jsx9("p", {
|
|
4530
4728
|
className: "skippr:text-xs skippr:text-muted-foreground",
|
|
4531
4729
|
children: label
|
|
4532
4730
|
})
|
|
@@ -4535,11 +4733,11 @@ function LoadingDots({ label }) {
|
|
|
4535
4733
|
}
|
|
4536
4734
|
|
|
4537
4735
|
// src/components/LoginFlow.tsx
|
|
4538
|
-
import { useCallback as useCallback13, useEffect as
|
|
4736
|
+
import { useCallback as useCallback13, useEffect as useEffect23, useRef as useRef15, useState as useState16 } from "react";
|
|
4539
4737
|
|
|
4540
4738
|
// src/components/ui/button.tsx
|
|
4541
4739
|
import { forwardRef as forwardRef3 } from "react";
|
|
4542
|
-
import { jsx as
|
|
4740
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
4543
4741
|
var variantClasses = {
|
|
4544
4742
|
default: "skippr:bg-primary skippr:text-primary-foreground skippr:hover:bg-primary/90",
|
|
4545
4743
|
destructive: "skippr:bg-destructive skippr:text-white skippr:hover:bg-destructive/90",
|
|
@@ -4558,7 +4756,7 @@ var sizeClasses = {
|
|
|
4558
4756
|
"icon-lg": "skippr:size-10"
|
|
4559
4757
|
};
|
|
4560
4758
|
var Button = forwardRef3(({ className, variant = "default", size = "default", ...props }, ref) => {
|
|
4561
|
-
return /* @__PURE__ */
|
|
4759
|
+
return /* @__PURE__ */ jsx10("button", {
|
|
4562
4760
|
className: cn("skippr:inline-flex skippr:items-center skippr:justify-center skippr:gap-2 skippr:whitespace-nowrap skippr:rounded-md skippr:text-sm skippr:font-medium skippr:ring-offset-background skippr:transition-all skippr:cursor-pointer skippr:focus-visible:outline-none skippr:focus-visible:ring-2 skippr:focus-visible:ring-ring skippr:focus-visible:ring-offset-2 skippr:disabled:pointer-events-none skippr:disabled:opacity-50 skippr:shrink-0 skippr:[&_svg]:pointer-events-none skippr:[&_svg:not([class*='size-'])]:size-4 skippr:[&_svg]:shrink-0", variantClasses[variant], sizeClasses[size], className),
|
|
4563
4761
|
ref,
|
|
4564
4762
|
...props
|
|
@@ -4567,12 +4765,12 @@ var Button = forwardRef3(({ className, variant = "default", size = "default", ..
|
|
|
4567
4765
|
Button.displayName = "Button";
|
|
4568
4766
|
|
|
4569
4767
|
// src/components/LoginFlow.tsx
|
|
4570
|
-
import { jsx as
|
|
4768
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4571
4769
|
var OTP_LENGTH = 6;
|
|
4572
4770
|
var DIGIT_KEYS = ["d0", "d1", "d2", "d3", "d4", "d5"];
|
|
4573
4771
|
function LoginFlow({ requestOtp, verifyOtp, error, isSubmitting }) {
|
|
4574
|
-
const [step, setStep] =
|
|
4575
|
-
const [email, setEmail] =
|
|
4772
|
+
const [step, setStep] = useState16("email");
|
|
4773
|
+
const [email, setEmail] = useState16("");
|
|
4576
4774
|
const handleRequestOtp = useCallback13(async (emailValue) => {
|
|
4577
4775
|
const success = await requestOtp(emailValue);
|
|
4578
4776
|
if (success)
|
|
@@ -4588,7 +4786,7 @@ function LoginFlow({ requestOtp, verifyOtp, error, isSubmitting }) {
|
|
|
4588
4786
|
await requestOtp(email);
|
|
4589
4787
|
}, [requestOtp, email]);
|
|
4590
4788
|
if (step === "otp") {
|
|
4591
|
-
return /* @__PURE__ */
|
|
4789
|
+
return /* @__PURE__ */ jsx11(OtpStep, {
|
|
4592
4790
|
email,
|
|
4593
4791
|
onSubmit: handleVerifyOtp,
|
|
4594
4792
|
onResend: handleResend,
|
|
@@ -4597,7 +4795,7 @@ function LoginFlow({ requestOtp, verifyOtp, error, isSubmitting }) {
|
|
|
4597
4795
|
isSubmitting
|
|
4598
4796
|
});
|
|
4599
4797
|
}
|
|
4600
|
-
return /* @__PURE__ */
|
|
4798
|
+
return /* @__PURE__ */ jsx11(EmailStep, {
|
|
4601
4799
|
email,
|
|
4602
4800
|
onEmailChange: setEmail,
|
|
4603
4801
|
onSubmit: handleRequestOtp,
|
|
@@ -4617,14 +4815,14 @@ function EmailStep({ email, onEmailChange, onSubmit, error, isSubmitting }) {
|
|
|
4617
4815
|
/* @__PURE__ */ jsxs9("div", {
|
|
4618
4816
|
className: "skippr:mb-4 skippr:text-center",
|
|
4619
4817
|
children: [
|
|
4620
|
-
/* @__PURE__ */
|
|
4818
|
+
/* @__PURE__ */ jsx11(Mail, {
|
|
4621
4819
|
className: "skippr:mx-auto skippr:mb-2 skippr:size-6 skippr:text-primary"
|
|
4622
4820
|
}),
|
|
4623
|
-
/* @__PURE__ */
|
|
4821
|
+
/* @__PURE__ */ jsx11("p", {
|
|
4624
4822
|
className: "skippr:text-sm skippr:font-medium skippr:text-foreground",
|
|
4625
4823
|
children: "Sign in to continue"
|
|
4626
4824
|
}),
|
|
4627
|
-
/* @__PURE__ */
|
|
4825
|
+
/* @__PURE__ */ jsx11("p", {
|
|
4628
4826
|
className: "skippr:mt-1 skippr:text-xs skippr:text-muted-foreground",
|
|
4629
4827
|
children: "Your email will be used to identify you across sessions"
|
|
4630
4828
|
})
|
|
@@ -4634,7 +4832,7 @@ function EmailStep({ email, onEmailChange, onSubmit, error, isSubmitting }) {
|
|
|
4634
4832
|
onSubmit: handleSubmit,
|
|
4635
4833
|
className: "skippr:flex skippr:flex-col skippr:gap-3",
|
|
4636
4834
|
children: [
|
|
4637
|
-
/* @__PURE__ */
|
|
4835
|
+
/* @__PURE__ */ jsx11("input", {
|
|
4638
4836
|
type: "email",
|
|
4639
4837
|
placeholder: "you@example.com",
|
|
4640
4838
|
value: email,
|
|
@@ -4643,15 +4841,15 @@ function EmailStep({ email, onEmailChange, onSubmit, error, isSubmitting }) {
|
|
|
4643
4841
|
required: true,
|
|
4644
4842
|
className: "skippr:w-full skippr:rounded-md skippr:border skippr:border-border skippr:bg-background skippr:px-3 skippr:py-2 skippr:text-sm skippr:text-foreground skippr:placeholder-muted-foreground skippr:outline-none focus:skippr:ring-2 focus:skippr:ring-primary/30 focus:skippr:border-primary disabled:skippr:opacity-50"
|
|
4645
4843
|
}),
|
|
4646
|
-
/* @__PURE__ */
|
|
4844
|
+
/* @__PURE__ */ jsx11(Button, {
|
|
4647
4845
|
type: "submit",
|
|
4648
4846
|
disabled: isSubmitting || !email.trim(),
|
|
4649
4847
|
className: "skippr:w-full",
|
|
4650
|
-
children: isSubmitting ? /* @__PURE__ */
|
|
4848
|
+
children: isSubmitting ? /* @__PURE__ */ jsx11(LoaderCircle, {
|
|
4651
4849
|
className: "skippr:size-4 skippr:animate-spin"
|
|
4652
4850
|
}) : "Continue"
|
|
4653
4851
|
}),
|
|
4654
|
-
error && /* @__PURE__ */
|
|
4852
|
+
error && /* @__PURE__ */ jsx11("p", {
|
|
4655
4853
|
className: "skippr:text-xs skippr:text-center skippr:text-destructive",
|
|
4656
4854
|
children: error
|
|
4657
4855
|
})
|
|
@@ -4661,18 +4859,18 @@ function EmailStep({ email, onEmailChange, onSubmit, error, isSubmitting }) {
|
|
|
4661
4859
|
});
|
|
4662
4860
|
}
|
|
4663
4861
|
function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
|
|
4664
|
-
const [digits, setDigits] =
|
|
4665
|
-
const [resendCooldown, setResendCooldown] =
|
|
4666
|
-
const inputRefs =
|
|
4667
|
-
const submittedRef =
|
|
4668
|
-
|
|
4862
|
+
const [digits, setDigits] = useState16(Array(OTP_LENGTH).fill(""));
|
|
4863
|
+
const [resendCooldown, setResendCooldown] = useState16(0);
|
|
4864
|
+
const inputRefs = useRef15([]);
|
|
4865
|
+
const submittedRef = useRef15(false);
|
|
4866
|
+
useEffect23(() => {
|
|
4669
4867
|
inputRefs.current[0]?.focus();
|
|
4670
4868
|
}, []);
|
|
4671
|
-
|
|
4869
|
+
useEffect23(() => {
|
|
4672
4870
|
if (error)
|
|
4673
4871
|
submittedRef.current = false;
|
|
4674
4872
|
}, [error]);
|
|
4675
|
-
|
|
4873
|
+
useEffect23(() => {
|
|
4676
4874
|
if (resendCooldown <= 0)
|
|
4677
4875
|
return;
|
|
4678
4876
|
const timer = setTimeout(() => setResendCooldown((c) => c - 1), 1000);
|
|
@@ -4737,7 +4935,7 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
|
|
|
4737
4935
|
/* @__PURE__ */ jsxs9("div", {
|
|
4738
4936
|
className: "skippr:mb-4 skippr:text-center",
|
|
4739
4937
|
children: [
|
|
4740
|
-
/* @__PURE__ */
|
|
4938
|
+
/* @__PURE__ */ jsx11("p", {
|
|
4741
4939
|
className: "skippr:text-sm skippr:font-medium skippr:text-foreground",
|
|
4742
4940
|
children: "Enter verification code"
|
|
4743
4941
|
}),
|
|
@@ -4746,7 +4944,7 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
|
|
|
4746
4944
|
children: [
|
|
4747
4945
|
"We sent a 6-digit code to",
|
|
4748
4946
|
" ",
|
|
4749
|
-
/* @__PURE__ */
|
|
4947
|
+
/* @__PURE__ */ jsx11("span", {
|
|
4750
4948
|
className: "skippr:font-medium skippr:text-foreground",
|
|
4751
4949
|
children: email
|
|
4752
4950
|
})
|
|
@@ -4758,9 +4956,9 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
|
|
|
4758
4956
|
onSubmit: handleSubmit,
|
|
4759
4957
|
className: "skippr:flex skippr:flex-col skippr:gap-3",
|
|
4760
4958
|
children: [
|
|
4761
|
-
/* @__PURE__ */
|
|
4959
|
+
/* @__PURE__ */ jsx11("div", {
|
|
4762
4960
|
className: "skippr:flex skippr:justify-center skippr:gap-1.5",
|
|
4763
|
-
children: digits.map((digit, index2) => /* @__PURE__ */
|
|
4961
|
+
children: digits.map((digit, index2) => /* @__PURE__ */ jsx11("input", {
|
|
4764
4962
|
ref: (el) => {
|
|
4765
4963
|
inputRefs.current[index2] = el;
|
|
4766
4964
|
},
|
|
@@ -4775,29 +4973,29 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
|
|
|
4775
4973
|
className: "skippr:h-10 skippr:w-10 skippr:rounded-md skippr:border skippr:border-border skippr:bg-background skippr:text-center skippr:text-sm skippr:font-semibold skippr:text-foreground skippr:outline-none focus:skippr:ring-2 focus:skippr:ring-primary/30 focus:skippr:border-primary disabled:skippr:opacity-50"
|
|
4776
4974
|
}, DIGIT_KEYS[index2]))
|
|
4777
4975
|
}),
|
|
4778
|
-
error && /* @__PURE__ */
|
|
4976
|
+
error && /* @__PURE__ */ jsx11("p", {
|
|
4779
4977
|
className: "skippr:text-xs skippr:text-center skippr:text-destructive",
|
|
4780
4978
|
children: error
|
|
4781
4979
|
}),
|
|
4782
|
-
/* @__PURE__ */
|
|
4980
|
+
/* @__PURE__ */ jsx11(Button, {
|
|
4783
4981
|
type: "submit",
|
|
4784
4982
|
disabled: isSubmitting || digits.join("").length !== OTP_LENGTH,
|
|
4785
4983
|
className: "skippr:w-full",
|
|
4786
|
-
children: isSubmitting ? /* @__PURE__ */
|
|
4984
|
+
children: isSubmitting ? /* @__PURE__ */ jsx11(LoaderCircle, {
|
|
4787
4985
|
className: "skippr:size-4 skippr:animate-spin"
|
|
4788
4986
|
}) : "Verify"
|
|
4789
4987
|
}),
|
|
4790
4988
|
/* @__PURE__ */ jsxs9("div", {
|
|
4791
4989
|
className: "skippr:flex skippr:items-center skippr:justify-between skippr:text-xs",
|
|
4792
4990
|
children: [
|
|
4793
|
-
/* @__PURE__ */
|
|
4991
|
+
/* @__PURE__ */ jsx11("button", {
|
|
4794
4992
|
type: "button",
|
|
4795
4993
|
onClick: onBack,
|
|
4796
4994
|
disabled: isSubmitting,
|
|
4797
4995
|
className: "skippr:text-muted-foreground hover:skippr:text-foreground skippr:transition-colors disabled:skippr:opacity-50",
|
|
4798
4996
|
children: "Change email"
|
|
4799
4997
|
}),
|
|
4800
|
-
/* @__PURE__ */
|
|
4998
|
+
/* @__PURE__ */ jsx11("button", {
|
|
4801
4999
|
type: "button",
|
|
4802
5000
|
onClick: handleResend,
|
|
4803
5001
|
disabled: isSubmitting || resendCooldown > 0,
|
|
@@ -4813,17 +5011,17 @@ function OtpStep({ email, onSubmit, onResend, onBack, error, isSubmitting }) {
|
|
|
4813
5011
|
}
|
|
4814
5012
|
|
|
4815
5013
|
// src/components/MessageList.tsx
|
|
4816
|
-
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";
|
|
4817
5015
|
|
|
4818
5016
|
// src/components/ChatInput.tsx
|
|
4819
|
-
import { useEffect as
|
|
4820
|
-
import { jsx as
|
|
5017
|
+
import { useEffect as useEffect24, useRef as useRef16, useState as useState17 } from "react";
|
|
5018
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4821
5019
|
var MAX_INPUT_HEIGHT = 60;
|
|
4822
5020
|
function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
|
|
4823
|
-
const [inputText, setInputText] =
|
|
4824
|
-
const textareaRef =
|
|
5021
|
+
const [inputText, setInputText] = useState17("");
|
|
5022
|
+
const textareaRef = useRef16(null);
|
|
4825
5023
|
const canSend = inputText.trim().length > 0 && !isSendingChat;
|
|
4826
|
-
|
|
5024
|
+
useEffect24(() => {
|
|
4827
5025
|
if (autoFocus)
|
|
4828
5026
|
textareaRef.current?.focus();
|
|
4829
5027
|
}, [autoFocus]);
|
|
@@ -4854,13 +5052,13 @@ function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
|
|
|
4854
5052
|
handleSubmit(e);
|
|
4855
5053
|
}
|
|
4856
5054
|
}
|
|
4857
|
-
return /* @__PURE__ */
|
|
5055
|
+
return /* @__PURE__ */ jsx12("form", {
|
|
4858
5056
|
onSubmit: handleSubmit,
|
|
4859
5057
|
className: "skippr:border-t skippr:border-border skippr:p-3",
|
|
4860
5058
|
children: /* @__PURE__ */ jsxs10("div", {
|
|
4861
5059
|
className: "skippr:flex skippr:items-center skippr:gap-2 skippr:rounded-xl skippr:bg-background skippr:ring-1 skippr:ring-foreground/10 skippr:px-3 skippr:py-2",
|
|
4862
5060
|
children: [
|
|
4863
|
-
/* @__PURE__ */
|
|
5061
|
+
/* @__PURE__ */ jsx12("textarea", {
|
|
4864
5062
|
ref: textareaRef,
|
|
4865
5063
|
rows: 1,
|
|
4866
5064
|
value: inputText,
|
|
@@ -4870,12 +5068,12 @@ function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
|
|
|
4870
5068
|
className: "skippr:flex-1 skippr:resize-none skippr:overflow-y-auto skippr:bg-transparent skippr:text-sm skippr:leading-5 skippr:text-foreground skippr:placeholder:text-muted-foreground skippr:outline-none",
|
|
4871
5069
|
style: { maxHeight: `${MAX_INPUT_HEIGHT}px` }
|
|
4872
5070
|
}),
|
|
4873
|
-
/* @__PURE__ */
|
|
5071
|
+
/* @__PURE__ */ jsx12("button", {
|
|
4874
5072
|
type: "submit",
|
|
4875
5073
|
disabled: !canSend,
|
|
4876
5074
|
"aria-label": "Send message",
|
|
4877
5075
|
className: cn("skippr:flex skippr:size-8 skippr:shrink-0 skippr:items-center skippr:justify-center skippr:rounded-lg skippr:transition-colors", canSend ? "skippr:bg-primary skippr:text-primary-foreground skippr:hover:bg-primary/90" : "skippr:bg-muted-foreground/20 skippr:text-muted-foreground/60"),
|
|
4878
|
-
children: /* @__PURE__ */
|
|
5076
|
+
children: /* @__PURE__ */ jsx12(Send, {
|
|
4879
5077
|
className: "skippr:size-3.5"
|
|
4880
5078
|
})
|
|
4881
5079
|
})
|
|
@@ -4885,7 +5083,7 @@ function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
|
|
|
4885
5083
|
}
|
|
4886
5084
|
|
|
4887
5085
|
// src/components/ChatMessage.tsx
|
|
4888
|
-
import { jsx as
|
|
5086
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4889
5087
|
function formatTimestamp(ts) {
|
|
4890
5088
|
return new Date(ts).toLocaleTimeString("en-US", {
|
|
4891
5089
|
hour: "numeric",
|
|
@@ -4895,16 +5093,16 @@ function formatTimestamp(ts) {
|
|
|
4895
5093
|
}
|
|
4896
5094
|
function ChatMessage({ message }) {
|
|
4897
5095
|
const isAgent = message.role === "assistant";
|
|
4898
|
-
return /* @__PURE__ */
|
|
5096
|
+
return /* @__PURE__ */ jsx13("div", {
|
|
4899
5097
|
className: cn("skippr:flex skippr:gap-2", isAgent ? "skippr:items-start" : "skippr:justify-end"),
|
|
4900
5098
|
children: /* @__PURE__ */ jsxs11("div", {
|
|
4901
5099
|
className: cn("skippr:flex skippr:max-w-[80%] skippr:flex-col", isAgent ? "skippr:items-start" : "skippr:items-end"),
|
|
4902
5100
|
children: [
|
|
4903
|
-
/* @__PURE__ */
|
|
5101
|
+
/* @__PURE__ */ jsx13("div", {
|
|
4904
5102
|
className: cn("skippr:rounded-2xl skippr:px-4 skippr:py-2.5 skippr:text-sm skippr:leading-relaxed", isAgent ? "skippr:border skippr:border-border skippr:bg-card skippr:text-foreground" : "skippr:bg-primary skippr:text-primary-foreground"),
|
|
4905
5103
|
children: message.content
|
|
4906
5104
|
}),
|
|
4907
|
-
message.timestamp && /* @__PURE__ */
|
|
5105
|
+
message.timestamp && /* @__PURE__ */ jsx13("span", {
|
|
4908
5106
|
className: "skippr:mt-1 skippr:px-1 skippr:text-[10px] skippr:text-muted-foreground/60",
|
|
4909
5107
|
children: formatTimestamp(message.timestamp)
|
|
4910
5108
|
})
|
|
@@ -4914,34 +5112,34 @@ function ChatMessage({ message }) {
|
|
|
4914
5112
|
}
|
|
4915
5113
|
|
|
4916
5114
|
// src/components/PlanCard.tsx
|
|
4917
|
-
import { useEffect as
|
|
4918
|
-
import { jsx as
|
|
5115
|
+
import { useEffect as useEffect25 } from "react";
|
|
5116
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4919
5117
|
var APPROVE_MESSAGE = "Yes, go ahead.";
|
|
4920
5118
|
var CANCEL_MESSAGE = "No, cancel that.";
|
|
4921
5119
|
var COMPLETED_CARD_VISIBLE_MS = 2500;
|
|
4922
5120
|
function StepIcon({ status }) {
|
|
4923
5121
|
if (status === "done") {
|
|
4924
|
-
return /* @__PURE__ */
|
|
5122
|
+
return /* @__PURE__ */ jsx14(CircleCheck, {
|
|
4925
5123
|
className: "skippr:size-4 skippr:text-chart-3"
|
|
4926
5124
|
});
|
|
4927
5125
|
}
|
|
4928
5126
|
if (status === "failed") {
|
|
4929
|
-
return /* @__PURE__ */
|
|
5127
|
+
return /* @__PURE__ */ jsx14(CircleX, {
|
|
4930
5128
|
className: "skippr:size-4 skippr:text-destructive"
|
|
4931
5129
|
});
|
|
4932
5130
|
}
|
|
4933
5131
|
if (status === "active") {
|
|
4934
|
-
return /* @__PURE__ */
|
|
5132
|
+
return /* @__PURE__ */ jsx14(Circle, {
|
|
4935
5133
|
className: "skippr:size-4 skippr:fill-primary/30 skippr:text-primary"
|
|
4936
5134
|
});
|
|
4937
5135
|
}
|
|
4938
|
-
return /* @__PURE__ */
|
|
5136
|
+
return /* @__PURE__ */ jsx14(Circle, {
|
|
4939
5137
|
className: "skippr:size-4 skippr:text-muted-foreground/30"
|
|
4940
5138
|
});
|
|
4941
5139
|
}
|
|
4942
5140
|
function PlanCard({ plan, sendChatMessage, onDismiss }) {
|
|
4943
5141
|
const awaitingApproval = plan.state === "proposed";
|
|
4944
|
-
|
|
5142
|
+
useEffect25(() => {
|
|
4945
5143
|
if (plan.state !== "completed")
|
|
4946
5144
|
return;
|
|
4947
5145
|
const timer = setTimeout(onDismiss, COMPLETED_CARD_VISIBLE_MS);
|
|
@@ -4950,19 +5148,19 @@ function PlanCard({ plan, sendChatMessage, onDismiss }) {
|
|
|
4950
5148
|
return /* @__PURE__ */ jsxs12("div", {
|
|
4951
5149
|
className: "skippr:rounded-2xl skippr:rounded-tl-md skippr:bg-card skippr:p-3.5 skippr:ring-2 skippr:ring-brand",
|
|
4952
5150
|
children: [
|
|
4953
|
-
/* @__PURE__ */
|
|
5151
|
+
/* @__PURE__ */ jsx14("p", {
|
|
4954
5152
|
className: "skippr:mb-3 skippr:text-sm skippr:font-semibold skippr:leading-snug skippr:text-foreground",
|
|
4955
5153
|
children: "Plan"
|
|
4956
5154
|
}),
|
|
4957
|
-
/* @__PURE__ */
|
|
5155
|
+
/* @__PURE__ */ jsx14("div", {
|
|
4958
5156
|
className: "skippr:space-y-2",
|
|
4959
5157
|
children: plan.steps.map((step) => /* @__PURE__ */ jsxs12("div", {
|
|
4960
5158
|
className: "skippr:flex skippr:items-center skippr:gap-2",
|
|
4961
5159
|
children: [
|
|
4962
|
-
/* @__PURE__ */
|
|
5160
|
+
/* @__PURE__ */ jsx14(StepIcon, {
|
|
4963
5161
|
status: step.status
|
|
4964
5162
|
}),
|
|
4965
|
-
/* @__PURE__ */
|
|
5163
|
+
/* @__PURE__ */ jsx14("p", {
|
|
4966
5164
|
className: cn("skippr:text-sm skippr:leading-snug", step.status === "done" && "skippr:text-muted-foreground skippr:line-through", step.status === "active" && "skippr:font-medium skippr:text-foreground", step.status === "pending" && "skippr:text-muted-foreground", step.status === "failed" && "skippr:text-destructive"),
|
|
4967
5165
|
children: step.label
|
|
4968
5166
|
})
|
|
@@ -4972,12 +5170,12 @@ function PlanCard({ plan, sendChatMessage, onDismiss }) {
|
|
|
4972
5170
|
awaitingApproval && /* @__PURE__ */ jsxs12("div", {
|
|
4973
5171
|
className: "skippr:mt-3.5 skippr:flex skippr:gap-2",
|
|
4974
5172
|
children: [
|
|
4975
|
-
/* @__PURE__ */
|
|
5173
|
+
/* @__PURE__ */ jsx14(Button, {
|
|
4976
5174
|
className: "skippr:flex-1 skippr:py-2",
|
|
4977
5175
|
onClick: () => sendChatMessage(APPROVE_MESSAGE),
|
|
4978
5176
|
children: "Approve"
|
|
4979
5177
|
}),
|
|
4980
|
-
/* @__PURE__ */
|
|
5178
|
+
/* @__PURE__ */ jsx14(Button, {
|
|
4981
5179
|
variant: "outline",
|
|
4982
5180
|
className: "skippr:flex-1 skippr:py-2",
|
|
4983
5181
|
onClick: () => sendChatMessage(CANCEL_MESSAGE),
|
|
@@ -4990,26 +5188,26 @@ function PlanCard({ plan, sendChatMessage, onDismiss }) {
|
|
|
4990
5188
|
}
|
|
4991
5189
|
|
|
4992
5190
|
// src/components/TypingIndicator.tsx
|
|
4993
|
-
import { jsx as
|
|
5191
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4994
5192
|
function TypingIndicator() {
|
|
4995
|
-
return /* @__PURE__ */
|
|
5193
|
+
return /* @__PURE__ */ jsx15("div", {
|
|
4996
5194
|
className: "skippr:flex skippr:items-start skippr:gap-2 skippr:animate-skippr-tab-fade",
|
|
4997
5195
|
children: /* @__PURE__ */ jsxs13("div", {
|
|
4998
5196
|
className: "skippr:inline-flex skippr:items-center skippr:gap-1 skippr:rounded-2xl skippr:border skippr:border-primary/20 skippr:bg-primary/10 skippr:px-4 skippr:py-2 skippr:text-xs skippr:text-primary",
|
|
4999
5197
|
children: [
|
|
5000
|
-
/* @__PURE__ */
|
|
5198
|
+
/* @__PURE__ */ jsx15("span", {
|
|
5001
5199
|
children: "Agent is analyzing your screen"
|
|
5002
5200
|
}),
|
|
5003
5201
|
/* @__PURE__ */ jsxs13("span", {
|
|
5004
5202
|
className: "skippr:inline-flex skippr:items-center skippr:gap-[2px]",
|
|
5005
5203
|
children: [
|
|
5006
|
-
/* @__PURE__ */
|
|
5204
|
+
/* @__PURE__ */ jsx15("span", {
|
|
5007
5205
|
className: "skippr:size-1 skippr:rounded-full skippr:bg-primary skippr:animate-skippr-thinking-dot skippr:[animation-delay:0ms]"
|
|
5008
5206
|
}),
|
|
5009
|
-
/* @__PURE__ */
|
|
5207
|
+
/* @__PURE__ */ jsx15("span", {
|
|
5010
5208
|
className: "skippr:size-1 skippr:rounded-full skippr:bg-primary skippr:animate-skippr-thinking-dot skippr:[animation-delay:200ms]"
|
|
5011
5209
|
}),
|
|
5012
|
-
/* @__PURE__ */
|
|
5210
|
+
/* @__PURE__ */ jsx15("span", {
|
|
5013
5211
|
className: "skippr:size-1 skippr:rounded-full skippr:bg-primary skippr:animate-skippr-thinking-dot skippr:[animation-delay:400ms]"
|
|
5014
5212
|
})
|
|
5015
5213
|
]
|
|
@@ -5020,7 +5218,7 @@ function TypingIndicator() {
|
|
|
5020
5218
|
}
|
|
5021
5219
|
|
|
5022
5220
|
// src/components/MessageList.tsx
|
|
5023
|
-
import { jsx as
|
|
5221
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5024
5222
|
var BOTTOM_THRESHOLD_PX = 32;
|
|
5025
5223
|
function isPlanVisible(plan) {
|
|
5026
5224
|
return !!plan && plan.steps.length > 0 && plan.state !== "abandoned";
|
|
@@ -5029,16 +5227,17 @@ function MessageList({
|
|
|
5029
5227
|
messages,
|
|
5030
5228
|
isStreaming,
|
|
5031
5229
|
sendChatMessage,
|
|
5032
|
-
isSendingChat,
|
|
5230
|
+
isSendingChat = false,
|
|
5033
5231
|
plan,
|
|
5034
|
-
autoFocus = false
|
|
5232
|
+
autoFocus = false,
|
|
5233
|
+
readOnly = false
|
|
5035
5234
|
}) {
|
|
5036
|
-
const containerRef =
|
|
5037
|
-
const isPinnedToBottom =
|
|
5038
|
-
const lastSeenMessageId =
|
|
5039
|
-
const [showJumpToLatest, setShowJumpToLatest] =
|
|
5235
|
+
const containerRef = useRef17(null);
|
|
5236
|
+
const isPinnedToBottom = useRef17(true);
|
|
5237
|
+
const lastSeenMessageId = useRef17(undefined);
|
|
5238
|
+
const [showJumpToLatest, setShowJumpToLatest] = useState18(false);
|
|
5040
5239
|
const lastMessage = messages.length > 0 ? messages[messages.length - 1] : undefined;
|
|
5041
|
-
const [dismissedPlanId, setDismissedPlanId] =
|
|
5240
|
+
const [dismissedPlanId, setDismissedPlanId] = useState18(null);
|
|
5042
5241
|
const dismissPlan = useCallback14(() => {
|
|
5043
5242
|
if (plan)
|
|
5044
5243
|
setDismissedPlanId(plan.planId);
|
|
@@ -5086,35 +5285,38 @@ function MessageList({
|
|
|
5086
5285
|
onScroll: handleScroll,
|
|
5087
5286
|
className: "skippr:min-h-0 skippr:flex-1 skippr:space-y-4 skippr:overflow-y-auto skippr:p-4 skippr:[overflow-anchor:none]",
|
|
5088
5287
|
children: [
|
|
5089
|
-
messages.length === 0 && !showTyping && /* @__PURE__ */
|
|
5288
|
+
messages.length === 0 && !showTyping && (readOnly ? /* @__PURE__ */ jsx16("p", {
|
|
5289
|
+
className: "skippr:px-2 skippr:py-6 skippr:text-center skippr:text-sm skippr:text-muted-foreground",
|
|
5290
|
+
children: "No messages in this conversation yet."
|
|
5291
|
+
}) : /* @__PURE__ */ jsx16(LoadingDots, {
|
|
5090
5292
|
label: "Waiting for conversation to begin..."
|
|
5091
|
-
}),
|
|
5092
|
-
messages.map((message) => /* @__PURE__ */
|
|
5293
|
+
})),
|
|
5294
|
+
messages.map((message) => /* @__PURE__ */ jsx16(ChatMessage, {
|
|
5093
5295
|
message
|
|
5094
5296
|
}, message.id)),
|
|
5095
|
-
showTyping && /* @__PURE__ */
|
|
5297
|
+
showTyping && /* @__PURE__ */ jsx16(TypingIndicator, {})
|
|
5096
5298
|
]
|
|
5097
5299
|
}),
|
|
5098
|
-
showJumpToLatest && /* @__PURE__ */
|
|
5300
|
+
showJumpToLatest && /* @__PURE__ */ jsx16("button", {
|
|
5099
5301
|
type: "button",
|
|
5100
5302
|
onClick: jumpToLatest,
|
|
5101
5303
|
"aria-label": "Jump to latest message",
|
|
5102
5304
|
className: "skippr:-translate-x-1/2 skippr:absolute skippr:bottom-3 skippr:left-1/2 skippr:flex skippr:min-h-11 skippr:min-w-11 skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:rounded-full skippr:border skippr:border-border skippr:bg-background skippr:p-1.5 skippr:text-foreground skippr:shadow-md skippr:transition-colors skippr:hover:bg-muted",
|
|
5103
|
-
children: /* @__PURE__ */
|
|
5305
|
+
children: /* @__PURE__ */ jsx16(ChevronDown, {
|
|
5104
5306
|
className: "skippr:size-4"
|
|
5105
5307
|
})
|
|
5106
5308
|
})
|
|
5107
5309
|
]
|
|
5108
5310
|
}),
|
|
5109
|
-
isPlanVisible(plan) && plan.planId !== dismissedPlanId && /* @__PURE__ */
|
|
5311
|
+
sendChatMessage && isPlanVisible(plan) && plan.planId !== dismissedPlanId && /* @__PURE__ */ jsx16("div", {
|
|
5110
5312
|
className: "skippr:shrink-0 skippr:border-t skippr:border-border skippr:p-3",
|
|
5111
|
-
children: /* @__PURE__ */
|
|
5313
|
+
children: /* @__PURE__ */ jsx16(PlanCard, {
|
|
5112
5314
|
plan,
|
|
5113
5315
|
sendChatMessage,
|
|
5114
5316
|
onDismiss: dismissPlan
|
|
5115
5317
|
}, plan.planId)
|
|
5116
5318
|
}),
|
|
5117
|
-
/* @__PURE__ */
|
|
5319
|
+
!readOnly && sendChatMessage && /* @__PURE__ */ jsx16(ChatInput, {
|
|
5118
5320
|
sendChatMessage,
|
|
5119
5321
|
isSendingChat,
|
|
5120
5322
|
autoFocus
|
|
@@ -5124,19 +5326,19 @@ function MessageList({
|
|
|
5124
5326
|
}
|
|
5125
5327
|
|
|
5126
5328
|
// src/components/SessionAgenda.tsx
|
|
5127
|
-
import { jsx as
|
|
5329
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
5128
5330
|
function SessionAgenda({ phases, hasStarted }) {
|
|
5129
5331
|
if (phases.length === 0 || !hasStarted) {
|
|
5130
|
-
return /* @__PURE__ */
|
|
5332
|
+
return /* @__PURE__ */ jsx17("div", {
|
|
5131
5333
|
className: "skippr:flex skippr:flex-1 skippr:items-center skippr:justify-center",
|
|
5132
|
-
children: /* @__PURE__ */
|
|
5334
|
+
children: /* @__PURE__ */ jsx17(LoadingDots, {
|
|
5133
5335
|
label: "Waiting for agenda to load..."
|
|
5134
5336
|
})
|
|
5135
5337
|
});
|
|
5136
5338
|
}
|
|
5137
|
-
return /* @__PURE__ */
|
|
5339
|
+
return /* @__PURE__ */ jsx17("div", {
|
|
5138
5340
|
className: "skippr:flex-1 skippr:overflow-y-auto skippr:px-4 skippr:py-4",
|
|
5139
|
-
children: /* @__PURE__ */
|
|
5341
|
+
children: /* @__PURE__ */ jsx17("div", {
|
|
5140
5342
|
className: "skippr:space-y-1",
|
|
5141
5343
|
children: phases.map((phase) => {
|
|
5142
5344
|
const isActive = phase.status === "active";
|
|
@@ -5144,29 +5346,29 @@ function SessionAgenda({ phases, hasStarted }) {
|
|
|
5144
5346
|
return /* @__PURE__ */ jsxs15("div", {
|
|
5145
5347
|
className: cn("skippr:flex skippr:items-start skippr:gap-2.5 skippr:rounded-lg skippr:p-2 skippr:transition-colors", isActive && "skippr:bg-primary/10"),
|
|
5146
5348
|
children: [
|
|
5147
|
-
/* @__PURE__ */
|
|
5349
|
+
/* @__PURE__ */ jsx17("div", {
|
|
5148
5350
|
className: "skippr:mt-0.5",
|
|
5149
|
-
children: isCompleted ? /* @__PURE__ */
|
|
5351
|
+
children: isCompleted ? /* @__PURE__ */ jsx17(CircleCheck, {
|
|
5150
5352
|
className: "skippr:size-4 skippr:text-chart-3"
|
|
5151
|
-
}) : isActive ? /* @__PURE__ */
|
|
5353
|
+
}) : isActive ? /* @__PURE__ */ jsx17(Circle, {
|
|
5152
5354
|
className: "skippr:size-4 skippr:fill-primary/30 skippr:text-primary"
|
|
5153
|
-
}) : /* @__PURE__ */
|
|
5355
|
+
}) : /* @__PURE__ */ jsx17(Circle, {
|
|
5154
5356
|
className: "skippr:size-4 skippr:text-muted-foreground/30"
|
|
5155
5357
|
})
|
|
5156
5358
|
}),
|
|
5157
5359
|
/* @__PURE__ */ jsxs15("div", {
|
|
5158
5360
|
className: "skippr:min-w-0 skippr:flex-1",
|
|
5159
5361
|
children: [
|
|
5160
|
-
/* @__PURE__ */
|
|
5362
|
+
/* @__PURE__ */ jsx17("p", {
|
|
5161
5363
|
className: cn("skippr:text-sm", isCompleted && "skippr:text-muted-foreground skippr:line-through", isActive && "skippr:font-medium skippr:text-foreground", phase.status === "pending" && "skippr:text-muted-foreground"),
|
|
5162
5364
|
children: phase.name
|
|
5163
5365
|
}),
|
|
5164
|
-
phase.highlights.length > 0 && /* @__PURE__ */
|
|
5366
|
+
phase.highlights.length > 0 && /* @__PURE__ */ jsx17("ul", {
|
|
5165
5367
|
className: "skippr:mt-1 skippr:space-y-0.5",
|
|
5166
5368
|
children: phase.highlights.map((text) => /* @__PURE__ */ jsxs15("li", {
|
|
5167
5369
|
className: cn("skippr:flex skippr:items-center skippr:gap-1.5 skippr:text-[11px] skippr:leading-tight", isCompleted ? "skippr:text-muted-foreground/40 skippr:line-through" : "skippr:text-muted-foreground/70"),
|
|
5168
5370
|
children: [
|
|
5169
|
-
/* @__PURE__ */
|
|
5371
|
+
/* @__PURE__ */ jsx17("span", {
|
|
5170
5372
|
className: "skippr:size-1 skippr:shrink-0 skippr:rounded-full skippr:bg-current"
|
|
5171
5373
|
}),
|
|
5172
5374
|
text
|
|
@@ -5183,61 +5385,20 @@ function SessionAgenda({ phases, hasStarted }) {
|
|
|
5183
5385
|
}
|
|
5184
5386
|
|
|
5185
5387
|
// src/components/SessionWarningBanner.tsx
|
|
5186
|
-
import { jsx as
|
|
5388
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
5187
5389
|
var SESSION_WARNING_THRESHOLD_SECS = 60;
|
|
5188
5390
|
function SessionWarningBanner({ remaining }) {
|
|
5189
5391
|
if (remaining === null || remaining <= 0 || remaining > SESSION_WARNING_THRESHOLD_SECS)
|
|
5190
5392
|
return null;
|
|
5191
|
-
return /* @__PURE__ */
|
|
5393
|
+
return /* @__PURE__ */ jsx18("div", {
|
|
5192
5394
|
"data-testid": "session-warning-banner",
|
|
5193
5395
|
className: "skippr:bg-red-50 skippr:px-4 skippr:py-1.5 skippr:text-center skippr:text-xs skippr:font-medium skippr:text-red-700",
|
|
5194
5396
|
children: "Session ending soon"
|
|
5195
5397
|
});
|
|
5196
5398
|
}
|
|
5197
5399
|
|
|
5198
|
-
// src/components/StartSessionPrompt.tsx
|
|
5199
|
-
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5200
|
-
var PROMPT_BUTTON = "skippr:cursor-pointer skippr:rounded-xl skippr:bg-primary skippr:px-8 skippr:py-3 skippr:text-sm skippr:font-medium skippr:text-primary-foreground skippr:transition-all skippr:hover:bg-primary/90 skippr:disabled:cursor-not-allowed skippr:disabled:opacity-60";
|
|
5201
|
-
function StartSessionPrompt({
|
|
5202
|
-
onStartSession,
|
|
5203
|
-
agentId,
|
|
5204
|
-
agentControls,
|
|
5205
|
-
isStarting,
|
|
5206
|
-
error,
|
|
5207
|
-
label = "Talk to Skippr",
|
|
5208
|
-
canResume = false,
|
|
5209
|
-
onResume
|
|
5210
|
-
}) {
|
|
5211
|
-
return /* @__PURE__ */ jsxs16("div", {
|
|
5212
|
-
className: "skippr:flex skippr:flex-1 skippr:flex-col skippr:items-center skippr:justify-center skippr:gap-3 skippr:px-4",
|
|
5213
|
-
children: [
|
|
5214
|
-
canResume && onResume ? /* @__PURE__ */ jsx18("button", {
|
|
5215
|
-
type: "button",
|
|
5216
|
-
onClick: onResume,
|
|
5217
|
-
disabled: isStarting,
|
|
5218
|
-
className: PROMPT_BUTTON,
|
|
5219
|
-
children: isStarting ? "Resuming..." : "Resume session"
|
|
5220
|
-
}) : /* @__PURE__ */ jsx18("button", {
|
|
5221
|
-
type: "button",
|
|
5222
|
-
onClick: () => {
|
|
5223
|
-
if (!agentId)
|
|
5224
|
-
return;
|
|
5225
|
-
onStartSession(agentControls ? { agentId, agentControls } : { agentId });
|
|
5226
|
-
},
|
|
5227
|
-
disabled: isStarting || !agentId,
|
|
5228
|
-
className: PROMPT_BUTTON,
|
|
5229
|
-
children: isStarting ? "Starting..." : label
|
|
5230
|
-
}),
|
|
5231
|
-
error && /* @__PURE__ */ jsx18("p", {
|
|
5232
|
-
className: "skippr:text-xs skippr:text-destructive",
|
|
5233
|
-
children: error
|
|
5234
|
-
})
|
|
5235
|
-
]
|
|
5236
|
-
});
|
|
5237
|
-
}
|
|
5238
|
-
|
|
5239
5400
|
// src/components/Sidebar.tsx
|
|
5240
|
-
import { jsx as jsx19, jsxs as
|
|
5401
|
+
import { jsx as jsx19, jsxs as jsxs16, Fragment as Fragment3 } from "react/jsx-runtime";
|
|
5241
5402
|
var PANEL_GAP_PX = 12;
|
|
5242
5403
|
var PANEL_VIEWPORT_MARGIN_PX = 24;
|
|
5243
5404
|
var PANEL_MAX_HEIGHT_PX = 460;
|
|
@@ -5254,9 +5415,6 @@ function Sidebar({
|
|
|
5254
5415
|
isPausing,
|
|
5255
5416
|
isPaused,
|
|
5256
5417
|
error,
|
|
5257
|
-
startSession,
|
|
5258
|
-
resumeSession,
|
|
5259
|
-
resumableSession,
|
|
5260
5418
|
isPanelOpen,
|
|
5261
5419
|
position,
|
|
5262
5420
|
isAuthenticated,
|
|
@@ -5268,17 +5426,26 @@ function Sidebar({
|
|
|
5268
5426
|
sidebarTab: activeTab,
|
|
5269
5427
|
setSidebarTab: setActiveTab,
|
|
5270
5428
|
autoFocusChat,
|
|
5271
|
-
agentId,
|
|
5272
5429
|
agentMode,
|
|
5273
|
-
|
|
5430
|
+
displayModules
|
|
5274
5431
|
} = useLiveAgent();
|
|
5275
|
-
const internalCtx =
|
|
5432
|
+
const internalCtx = useContext11(LiveAgentContext);
|
|
5433
|
+
const defaultAgentId = internalCtx?.defaultAgentId ?? null;
|
|
5434
|
+
const startDefaultSession = internalCtx?.startDefaultSession ?? (() => {});
|
|
5435
|
+
const talkDisabled = !(internalCtx?.hasResolvedModules ?? false);
|
|
5276
5436
|
const usesHostAuth = internalCtx?.usesHostAuth ?? false;
|
|
5277
5437
|
const authFailed = internalCtx?.authFailed ?? false;
|
|
5438
|
+
const idleHistory = internalCtx?.idleHistory ?? {
|
|
5439
|
+
messages: [],
|
|
5440
|
+
phases: [],
|
|
5441
|
+
isLoading: false
|
|
5442
|
+
};
|
|
5278
5443
|
const launcherBottomPx = internalCtx?.launcherBottomPx ?? DEFAULT_LAUNCHER_BOTTOM_PX;
|
|
5279
5444
|
const popsDown = internalCtx?.popsDown ?? false;
|
|
5280
5445
|
const panelExpanded = internalCtx?.panelExpanded ?? false;
|
|
5281
|
-
const
|
|
5446
|
+
const defaultModule = displayModules.find((m) => m.id === defaultAgentId) ?? null;
|
|
5447
|
+
const displayedMode = agentMode ?? defaultModule?.mode ?? null;
|
|
5448
|
+
const showAgenda = displayedMode !== AGENT_MODE.AlwaysOn;
|
|
5282
5449
|
const isFloating = variant === "floating";
|
|
5283
5450
|
const isSidebar = variant === "sidebar";
|
|
5284
5451
|
const inSession = isConnected || isStarting || isPausing;
|
|
@@ -5291,7 +5458,7 @@ function Sidebar({
|
|
|
5291
5458
|
height: panelExpanded ? availableHeight : `min(${PANEL_MAX_HEIGHT_PX}px, ${availableHeight})`
|
|
5292
5459
|
};
|
|
5293
5460
|
}
|
|
5294
|
-
|
|
5461
|
+
useEffect26(() => {
|
|
5295
5462
|
if (!isSidebar)
|
|
5296
5463
|
return;
|
|
5297
5464
|
const prop = position === "right" ? "marginRight" : "marginLeft";
|
|
@@ -5305,7 +5472,7 @@ function Sidebar({
|
|
|
5305
5472
|
document.body.style.transition = "";
|
|
5306
5473
|
};
|
|
5307
5474
|
}, [isSidebar, isPanelOpen, position]);
|
|
5308
|
-
return /* @__PURE__ */
|
|
5475
|
+
return /* @__PURE__ */ jsxs16("div", {
|
|
5309
5476
|
ref: internalCtx?.panelRef,
|
|
5310
5477
|
className: cn("skippr:fixed skippr:z-[9999]", "skippr:bg-card", "skippr:flex skippr:flex-col", "skippr:overflow-hidden", isFloating && "skippr:border skippr:border-border skippr:rounded-2xl skippr:shadow-[0_8px_30px_rgba(0,0,0,0.16),0_4px_12px_rgba(0,0,0,0.08)]", isFloating && (position === "right" ? "skippr:right-6" : "skippr:left-6"), isFloating && "skippr:transition-[opacity,transform,height] skippr:duration-300 skippr:ease-in-out", isFloating && (popsDown ? position === "right" ? "skippr:origin-top-right" : "skippr:origin-top-left" : position === "right" ? "skippr:origin-bottom-right" : "skippr:origin-bottom-left"), isFloating && !isPanelOpen && "skippr:scale-0 skippr:opacity-0 skippr:pointer-events-none", isFloating && isPanelOpen && "skippr:scale-100 skippr:opacity-100", isSidebar && "skippr:top-0 skippr:h-full", isSidebar && "skippr:transition-[width] skippr:duration-300 skippr:ease-in-out", isSidebar && position === "right" && "skippr:right-0 skippr:border-l skippr:border-l-border", isSidebar && position === "left" && "skippr:left-0 skippr:border-r skippr:border-r-border", isSidebar && !isPanelOpen && "skippr:w-0 skippr:border-0"),
|
|
5311
5478
|
style: { width: isPanelOpen ? SIDEBAR_WIDTH : undefined, ...floatingStyle },
|
|
@@ -5316,19 +5483,17 @@ function Sidebar({
|
|
|
5316
5483
|
isPaused,
|
|
5317
5484
|
isPausing,
|
|
5318
5485
|
isDisconnecting,
|
|
5319
|
-
canResume: resumableSession !== null,
|
|
5320
|
-
onStartSession: startSession,
|
|
5321
|
-
onResume: resumeSession,
|
|
5322
5486
|
isStarting,
|
|
5323
5487
|
error,
|
|
5324
5488
|
activeTab,
|
|
5325
5489
|
onTabChange: setActiveTab,
|
|
5326
5490
|
hideControls,
|
|
5327
|
-
startSessionLabel,
|
|
5328
5491
|
autoFocusChat,
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5492
|
+
showAgenda,
|
|
5493
|
+
idleHistory,
|
|
5494
|
+
onTalk: startDefaultSession,
|
|
5495
|
+
talkLabel: startSessionLabel,
|
|
5496
|
+
talkDisabled
|
|
5332
5497
|
}) : usesHostAuth || isValidating ? /* @__PURE__ */ jsx19("div", {
|
|
5333
5498
|
className: "skippr:flex skippr:flex-1 skippr:items-center skippr:justify-center",
|
|
5334
5499
|
children: /* @__PURE__ */ jsx19(LoadingDots, {
|
|
@@ -5348,35 +5513,31 @@ function AuthenticatedContent({
|
|
|
5348
5513
|
isPaused,
|
|
5349
5514
|
isPausing,
|
|
5350
5515
|
isDisconnecting,
|
|
5351
|
-
canResume,
|
|
5352
|
-
onStartSession,
|
|
5353
|
-
onResume,
|
|
5354
5516
|
isStarting,
|
|
5355
5517
|
error,
|
|
5356
5518
|
activeTab,
|
|
5357
5519
|
onTabChange,
|
|
5358
5520
|
hideControls,
|
|
5359
|
-
startSessionLabel,
|
|
5360
5521
|
autoFocusChat,
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5522
|
+
showAgenda,
|
|
5523
|
+
idleHistory,
|
|
5524
|
+
onTalk,
|
|
5525
|
+
talkLabel,
|
|
5526
|
+
talkDisabled
|
|
5364
5527
|
}) {
|
|
5365
5528
|
const inSession = isConnected || isStarting || isPaused || isPausing;
|
|
5366
5529
|
const effectiveTab = showAgenda ? activeTab : "chat";
|
|
5367
5530
|
let transitionLabel = null;
|
|
5368
5531
|
if (isStarting && !isConnected) {
|
|
5369
5532
|
transitionLabel = "Reconnecting...";
|
|
5370
|
-
} else if (isPaused) {
|
|
5371
|
-
transitionLabel = "Paused";
|
|
5372
5533
|
}
|
|
5373
|
-
return /* @__PURE__ */
|
|
5534
|
+
return /* @__PURE__ */ jsxs16(Fragment3, {
|
|
5374
5535
|
children: [
|
|
5375
5536
|
isConnected && /* @__PURE__ */ jsx19(ConnectedBanner, {}),
|
|
5376
|
-
showAgenda && /* @__PURE__ */
|
|
5537
|
+
showAgenda && /* @__PURE__ */ jsxs16("div", {
|
|
5377
5538
|
className: "skippr:flex skippr:items-center skippr:gap-2 skippr:border-b skippr:border-border skippr:px-3 skippr:py-1",
|
|
5378
5539
|
children: [
|
|
5379
|
-
/* @__PURE__ */
|
|
5540
|
+
/* @__PURE__ */ jsxs16("button", {
|
|
5380
5541
|
type: "button",
|
|
5381
5542
|
className: cn("skippr:relative skippr:inline-flex skippr:cursor-pointer skippr:items-center skippr:gap-1.5 skippr:rounded-lg skippr:px-3 skippr:py-1.5 skippr:text-sm skippr:font-medium skippr:transition-all", activeTab === "chat" ? "skippr:text-foreground" : "skippr:text-muted-foreground skippr:hover:text-foreground"),
|
|
5382
5543
|
onClick: () => onTabChange("chat"),
|
|
@@ -5390,7 +5551,7 @@ function AuthenticatedContent({
|
|
|
5390
5551
|
})
|
|
5391
5552
|
]
|
|
5392
5553
|
}),
|
|
5393
|
-
/* @__PURE__ */
|
|
5554
|
+
/* @__PURE__ */ jsxs16("button", {
|
|
5394
5555
|
type: "button",
|
|
5395
5556
|
className: cn("skippr:relative skippr:inline-flex skippr:cursor-pointer skippr:items-center skippr:gap-1.5 skippr:rounded-lg skippr:px-3 skippr:py-1.5 skippr:text-sm skippr:font-medium skippr:transition-all", activeTab === "agenda" ? "skippr:text-foreground" : "skippr:text-muted-foreground skippr:hover:text-foreground"),
|
|
5396
5557
|
onClick: () => onTabChange("agenda"),
|
|
@@ -5413,7 +5574,7 @@ function AuthenticatedContent({
|
|
|
5413
5574
|
children: /* @__PURE__ */ jsx19(LoadingDots, {
|
|
5414
5575
|
label: "Ending session..."
|
|
5415
5576
|
})
|
|
5416
|
-
}) : inSession ? /* @__PURE__ */
|
|
5577
|
+
}) : inSession ? /* @__PURE__ */ jsxs16(Fragment3, {
|
|
5417
5578
|
children: [
|
|
5418
5579
|
transitionLabel && /* @__PURE__ */ jsx19("div", {
|
|
5419
5580
|
className: "skippr:shrink-0 skippr:border-b skippr:border-border skippr:bg-muted/50 skippr:px-3 skippr:py-1.5 skippr:text-center skippr:text-xs skippr:text-muted-foreground",
|
|
@@ -5424,26 +5585,21 @@ function AuthenticatedContent({
|
|
|
5424
5585
|
autoFocusChat
|
|
5425
5586
|
})
|
|
5426
5587
|
]
|
|
5427
|
-
}) : /* @__PURE__ */ jsx19(
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
label: startSessionLabel,
|
|
5436
|
-
canResume,
|
|
5437
|
-
onResume
|
|
5438
|
-
})
|
|
5439
|
-
}, `${activeTab}-empty`)
|
|
5588
|
+
}) : /* @__PURE__ */ jsx19(IdleHistory, {
|
|
5589
|
+
activeTab: effectiveTab,
|
|
5590
|
+
history: idleHistory,
|
|
5591
|
+
onTalk,
|
|
5592
|
+
talkLabel,
|
|
5593
|
+
talkDisabled,
|
|
5594
|
+
error
|
|
5595
|
+
})
|
|
5440
5596
|
}),
|
|
5441
5597
|
!hideControls && /* @__PURE__ */ jsx19("div", {
|
|
5442
5598
|
className: "skippr:shrink-0 skippr:border-t skippr:border-border",
|
|
5443
|
-
children: /* @__PURE__ */
|
|
5599
|
+
children: /* @__PURE__ */ jsxs16("div", {
|
|
5444
5600
|
className: "skippr:flex skippr:items-center skippr:justify-center skippr:gap-1 skippr:px-4 skippr:pt-1.5 skippr:pb-2 skippr:text-[10px] skippr:text-muted-foreground",
|
|
5445
5601
|
children: [
|
|
5446
|
-
/* @__PURE__ */
|
|
5602
|
+
/* @__PURE__ */ jsxs16("svg", {
|
|
5447
5603
|
viewBox: "21 21 109 109",
|
|
5448
5604
|
className: "skippr:size-3",
|
|
5449
5605
|
fill: "none",
|
|
@@ -5467,7 +5623,7 @@ function AuthenticatedContent({
|
|
|
5467
5623
|
});
|
|
5468
5624
|
}
|
|
5469
5625
|
function AuthError() {
|
|
5470
|
-
return /* @__PURE__ */
|
|
5626
|
+
return /* @__PURE__ */ jsxs16("div", {
|
|
5471
5627
|
className: "skippr:flex skippr:flex-1 skippr:flex-col skippr:items-center skippr:justify-center skippr:px-6 skippr:py-4 skippr:text-center",
|
|
5472
5628
|
children: [
|
|
5473
5629
|
/* @__PURE__ */ jsx19(CircleAlert, {
|
|
@@ -5490,6 +5646,60 @@ function ConnectedBanner() {
|
|
|
5490
5646
|
remaining
|
|
5491
5647
|
});
|
|
5492
5648
|
}
|
|
5649
|
+
function IdleHistory({
|
|
5650
|
+
activeTab,
|
|
5651
|
+
history: history2,
|
|
5652
|
+
onTalk,
|
|
5653
|
+
talkLabel,
|
|
5654
|
+
talkDisabled,
|
|
5655
|
+
error
|
|
5656
|
+
}) {
|
|
5657
|
+
if (history2.isLoading) {
|
|
5658
|
+
return /* @__PURE__ */ jsx19("div", {
|
|
5659
|
+
className: "skippr:flex skippr:flex-1 skippr:items-center skippr:justify-center",
|
|
5660
|
+
children: /* @__PURE__ */ jsx19(LoadingDots, {
|
|
5661
|
+
label: "Loading conversation..."
|
|
5662
|
+
})
|
|
5663
|
+
});
|
|
5664
|
+
}
|
|
5665
|
+
return /* @__PURE__ */ jsxs16("div", {
|
|
5666
|
+
className: "skippr:flex skippr:min-h-0 skippr:flex-1 skippr:flex-col skippr:animate-skippr-tab-fade",
|
|
5667
|
+
children: [
|
|
5668
|
+
activeTab === "agenda" ? /* @__PURE__ */ jsx19("div", {
|
|
5669
|
+
className: "skippr:min-h-0 skippr:flex-1 skippr:overflow-y-auto",
|
|
5670
|
+
children: /* @__PURE__ */ jsx19(SessionAgenda, {
|
|
5671
|
+
phases: history2.phases,
|
|
5672
|
+
hasStarted: history2.phases.length > 0
|
|
5673
|
+
})
|
|
5674
|
+
}) : /* @__PURE__ */ jsx19(MessageList, {
|
|
5675
|
+
messages: history2.messages,
|
|
5676
|
+
isStreaming: false,
|
|
5677
|
+
readOnly: true
|
|
5678
|
+
}),
|
|
5679
|
+
/* @__PURE__ */ jsxs16("div", {
|
|
5680
|
+
className: "skippr:shrink-0 skippr:border-t skippr:border-border skippr:p-3",
|
|
5681
|
+
children: [
|
|
5682
|
+
/* @__PURE__ */ jsxs16("button", {
|
|
5683
|
+
type: "button",
|
|
5684
|
+
onClick: onTalk,
|
|
5685
|
+
disabled: talkDisabled,
|
|
5686
|
+
className: "skippr:flex skippr:w-full skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:gap-2 skippr:rounded-xl skippr:bg-primary skippr:px-4 skippr:py-3 skippr:font-semibold skippr:text-[13px] skippr:text-primary-foreground skippr:transition-colors skippr:hover:bg-primary/90 skippr:disabled:cursor-not-allowed skippr:disabled:opacity-50",
|
|
5687
|
+
children: [
|
|
5688
|
+
/* @__PURE__ */ jsx19(Mic, {
|
|
5689
|
+
className: "skippr:size-4"
|
|
5690
|
+
}),
|
|
5691
|
+
talkLabel
|
|
5692
|
+
]
|
|
5693
|
+
}),
|
|
5694
|
+
error && /* @__PURE__ */ jsx19("p", {
|
|
5695
|
+
className: "skippr:mt-2 skippr:text-center skippr:text-xs skippr:text-destructive",
|
|
5696
|
+
children: error
|
|
5697
|
+
})
|
|
5698
|
+
]
|
|
5699
|
+
})
|
|
5700
|
+
]
|
|
5701
|
+
}, `idle-${activeTab}`);
|
|
5702
|
+
}
|
|
5493
5703
|
function ConnectedBody({
|
|
5494
5704
|
activeTab,
|
|
5495
5705
|
autoFocusChat
|
|
@@ -5497,7 +5707,8 @@ function ConnectedBody({
|
|
|
5497
5707
|
const { allMessages, agentState, sendChatMessage, isSendingChat } = useCombinedMessages();
|
|
5498
5708
|
const { phases } = usePhaseUpdates();
|
|
5499
5709
|
const plan = usePlanUpdates();
|
|
5500
|
-
const { agentControls } = useLiveAgent();
|
|
5710
|
+
const { agentControls, isPaused } = useLiveAgent();
|
|
5711
|
+
const { isHeld } = useSessionHoldContext();
|
|
5501
5712
|
if (activeTab === "agenda") {
|
|
5502
5713
|
return /* @__PURE__ */ jsx19("div", {
|
|
5503
5714
|
className: "skippr:min-h-0 skippr:flex-1 skippr:overflow-y-auto skippr:animate-skippr-tab-fade",
|
|
@@ -5515,18 +5726,19 @@ function ConnectedBody({
|
|
|
5515
5726
|
sendChatMessage,
|
|
5516
5727
|
isSendingChat,
|
|
5517
5728
|
plan: agentControls?.actions ? plan : null,
|
|
5518
|
-
autoFocus: autoFocusChat
|
|
5729
|
+
autoFocus: autoFocusChat,
|
|
5730
|
+
readOnly: isPaused || isHeld
|
|
5519
5731
|
})
|
|
5520
5732
|
}, "chat");
|
|
5521
5733
|
}
|
|
5522
5734
|
|
|
5523
5735
|
// src/components/SidebarTrigger.tsx
|
|
5524
|
-
import { useContext as
|
|
5736
|
+
import { useContext as useContext12 } from "react";
|
|
5525
5737
|
|
|
5526
5738
|
// src/components/Logo.tsx
|
|
5527
|
-
import { jsx as jsx20, jsxs as
|
|
5739
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5528
5740
|
function Logo({ className }) {
|
|
5529
|
-
return /* @__PURE__ */
|
|
5741
|
+
return /* @__PURE__ */ jsxs17("svg", {
|
|
5530
5742
|
width: "1em",
|
|
5531
5743
|
height: "1em",
|
|
5532
5744
|
viewBox: "0 0 200 200",
|
|
@@ -5542,7 +5754,7 @@ function Logo({ className }) {
|
|
|
5542
5754
|
rx: "40",
|
|
5543
5755
|
fill: "#2D2D3F"
|
|
5544
5756
|
}),
|
|
5545
|
-
/* @__PURE__ */
|
|
5757
|
+
/* @__PURE__ */ jsxs17("g", {
|
|
5546
5758
|
transform: "translate(100 100) scale(0.8) translate(-100 -100)",
|
|
5547
5759
|
children: [
|
|
5548
5760
|
/* @__PURE__ */ jsx20("path", {
|
|
@@ -5573,7 +5785,7 @@ function SidebarTrigger() {
|
|
|
5573
5785
|
isStarting,
|
|
5574
5786
|
isPausing
|
|
5575
5787
|
} = useLiveAgent();
|
|
5576
|
-
const internalCtx =
|
|
5788
|
+
const internalCtx = useContext12(LiveAgentContext);
|
|
5577
5789
|
const launcherBottomPx = internalCtx?.launcherBottomPx ?? DEFAULT_LAUNCHER_BOTTOM_PX;
|
|
5578
5790
|
const popsDown = internalCtx?.popsDown ?? false;
|
|
5579
5791
|
if (isMinimized || isConnected || isStarting || isPausing)
|
|
@@ -5595,7 +5807,7 @@ function SidebarTrigger() {
|
|
|
5595
5807
|
}
|
|
5596
5808
|
|
|
5597
5809
|
// src/components/LiveAgent.tsx
|
|
5598
|
-
import { jsx as jsx22, jsxs as
|
|
5810
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5599
5811
|
function readSavedLauncherBottom() {
|
|
5600
5812
|
try {
|
|
5601
5813
|
const saved = Number.parseInt(localStorage.getItem("skippr_widget_bottom") ?? "", 10);
|
|
@@ -5613,8 +5825,8 @@ function AgentCursorMount({ animated }) {
|
|
|
5613
5825
|
function PlanPanelOpener() {
|
|
5614
5826
|
const plan = usePlanUpdates();
|
|
5615
5827
|
const { expandPanel } = useLiveAgent();
|
|
5616
|
-
const surfacedPlanIdRef =
|
|
5617
|
-
|
|
5828
|
+
const surfacedPlanIdRef = useRef18(null);
|
|
5829
|
+
useEffect27(() => {
|
|
5618
5830
|
if (plan?.state !== "proposed" || surfacedPlanIdRef.current === plan.planId)
|
|
5619
5831
|
return;
|
|
5620
5832
|
surfacedPlanIdRef.current = plan.planId;
|
|
@@ -5654,7 +5866,7 @@ function LiveAgent(props) {
|
|
|
5654
5866
|
const auth = useAuth({ appKey });
|
|
5655
5867
|
const usesHostAuth = !!getUserToken || !!userToken || !!authTokenProp;
|
|
5656
5868
|
const effectiveAuthToken = usesHostAuth ? authTokenProp : auth.authToken ?? undefined;
|
|
5657
|
-
const [activeModule, setActiveModule] =
|
|
5869
|
+
const [activeModule, setActiveModule] = useState19(null);
|
|
5658
5870
|
const minimizeOnSessionStart = useCallback15(() => {
|
|
5659
5871
|
if (minimizable) {
|
|
5660
5872
|
setIsMinimized(true);
|
|
@@ -5700,7 +5912,7 @@ function LiveAgent(props) {
|
|
|
5700
5912
|
onStartError: expandOnSessionStartError,
|
|
5701
5913
|
onDisconnect: minimizeOnSessionDisconnect
|
|
5702
5914
|
});
|
|
5703
|
-
const teardownInFlightRef =
|
|
5915
|
+
const teardownInFlightRef = useRef18(false);
|
|
5704
5916
|
teardownInFlightRef.current = isPaused || isPausing || isDisconnecting;
|
|
5705
5917
|
const handleRoomDisconnected = useCallback15(() => {
|
|
5706
5918
|
if (teardownInFlightRef.current)
|
|
@@ -5708,27 +5920,28 @@ function LiveAgent(props) {
|
|
|
5708
5920
|
disconnect();
|
|
5709
5921
|
}, [disconnect]);
|
|
5710
5922
|
const isSessionLive = connection !== null || isStarting || isPausing || isDisconnecting;
|
|
5711
|
-
const [isPanelOpen, setIsPanelOpen] =
|
|
5712
|
-
const [isMinimized, setIsMinimized] =
|
|
5713
|
-
const [sidebarTab, setSidebarTab] =
|
|
5714
|
-
const [phasesSnapshot, setPhasesSnapshot] =
|
|
5715
|
-
const [textMode, setTextMode] =
|
|
5716
|
-
const [panelExpanded, setPanelExpanded] =
|
|
5923
|
+
const [isPanelOpen, setIsPanelOpen] = useState19(defaultOpen);
|
|
5924
|
+
const [isMinimized, setIsMinimized] = useState19(minimizable && !defaultOpen);
|
|
5925
|
+
const [sidebarTab, setSidebarTab] = useState19("agenda");
|
|
5926
|
+
const [phasesSnapshot, setPhasesSnapshot] = useState19([]);
|
|
5927
|
+
const [textMode, setTextMode] = useState19(false);
|
|
5928
|
+
const [panelExpanded, setPanelExpanded] = useState19(false);
|
|
5717
5929
|
const togglePanelExpanded = useCallback15(() => setPanelExpanded((prev) => !prev), []);
|
|
5718
|
-
const panelRef =
|
|
5719
|
-
const controlBarRef =
|
|
5720
|
-
const [isDragging, setIsDragging] =
|
|
5930
|
+
const panelRef = useRef18(null);
|
|
5931
|
+
const controlBarRef = useRef18(null);
|
|
5932
|
+
const [isDragging, setIsDragging] = useState19(false);
|
|
5721
5933
|
const setTextModeState = useCallback15((enabled) => {
|
|
5722
5934
|
setTextMode(enabled);
|
|
5723
5935
|
}, []);
|
|
5724
5936
|
const isConnected = connection !== null;
|
|
5725
5937
|
const showControlBar = isConnected || isStarting || isPausing;
|
|
5726
|
-
|
|
5938
|
+
useEffect27(() => {
|
|
5727
5939
|
if (!isConnected)
|
|
5728
5940
|
setTextModeState(false);
|
|
5729
5941
|
}, [isConnected, setTextModeState]);
|
|
5730
5942
|
const {
|
|
5731
5943
|
modules: availableModules,
|
|
5944
|
+
defaultSelection,
|
|
5732
5945
|
isLoading: isLoadingModules,
|
|
5733
5946
|
hasResolved: hasResolvedModules,
|
|
5734
5947
|
error: modulesError,
|
|
@@ -5736,20 +5949,20 @@ function LiveAgent(props) {
|
|
|
5736
5949
|
} = useAvailableModules({
|
|
5737
5950
|
enabled: !isSessionLive,
|
|
5738
5951
|
bearerToken,
|
|
5739
|
-
authedFetch
|
|
5952
|
+
authedFetch,
|
|
5953
|
+
agentId: hostAgentId ?? undefined
|
|
5740
5954
|
});
|
|
5741
5955
|
const { goals: adoptionGoals, attendGoal } = useAdoptionGoals({
|
|
5742
5956
|
enabled: !isSessionLive,
|
|
5743
5957
|
bearerToken,
|
|
5744
5958
|
authedFetch
|
|
5745
5959
|
});
|
|
5746
|
-
const
|
|
5747
|
-
const operatingModule = activeModule ?? (hostAgentId ? displayModules[0] ?? null : null);
|
|
5960
|
+
const operatingModule = activeModule ?? (hostAgentId ? availableModules[0] ?? null : null);
|
|
5748
5961
|
const agentId = operatingModule?.id ?? null;
|
|
5749
5962
|
const agentControls = operatingModule?.controls ?? hostAgentControls;
|
|
5750
5963
|
const agentMode = operatingModule?.mode ?? null;
|
|
5751
5964
|
const shouldAnimateCursor = operatingModule?.uiPreferences?.animateCursor ?? animateAgentCursor;
|
|
5752
|
-
const resumableSession =
|
|
5965
|
+
const resumableSession = useMemo7(() => getResumableSession(operatingModule), [operatingModule]);
|
|
5753
5966
|
const resumeSession = useCallback15(async () => {
|
|
5754
5967
|
if (!resumableSession)
|
|
5755
5968
|
return;
|
|
@@ -5759,7 +5972,7 @@ function LiveAgent(props) {
|
|
|
5759
5972
|
existingSessionId: resumableSession.id
|
|
5760
5973
|
});
|
|
5761
5974
|
}, [resumableSession, startSession, agentControls]);
|
|
5762
|
-
const selectModule = useCallback15((moduleId) => {
|
|
5975
|
+
const selectModule = useCallback15((moduleId, opts) => {
|
|
5763
5976
|
const found = availableModules.find((m) => m.id === moduleId);
|
|
5764
5977
|
if (!found)
|
|
5765
5978
|
return;
|
|
@@ -5767,7 +5980,8 @@ function LiveAgent(props) {
|
|
|
5767
5980
|
startSession({
|
|
5768
5981
|
agentId: found.id,
|
|
5769
5982
|
agentControls: found.controls,
|
|
5770
|
-
existingSessionId: getResumableSessionId(found.currentSession, found.mode)
|
|
5983
|
+
existingSessionId: getResumableSessionId(found.currentSession, found.mode),
|
|
5984
|
+
autoStarted: opts?.autoStarted
|
|
5771
5985
|
});
|
|
5772
5986
|
}, [availableModules, startSession]);
|
|
5773
5987
|
const startAdoptionSession = useCallback15((goal) => {
|
|
@@ -5781,9 +5995,9 @@ function LiveAgent(props) {
|
|
|
5781
5995
|
adoptionGoalId: goal.goalId
|
|
5782
5996
|
});
|
|
5783
5997
|
}, [attendGoal, availableModules, startSession]);
|
|
5784
|
-
const [welcomeDismissed, setWelcomeDismissed] =
|
|
5998
|
+
const [welcomeDismissed, setWelcomeDismissed] = useState19(false);
|
|
5785
5999
|
const dismissWelcome = useCallback15(() => setWelcomeDismissed(true), []);
|
|
5786
|
-
const [currentPosition, setCurrentPosition] =
|
|
6000
|
+
const [currentPosition, setCurrentPosition] = useState19(() => {
|
|
5787
6001
|
try {
|
|
5788
6002
|
const saved = localStorage.getItem("skippr_widget_position");
|
|
5789
6003
|
if (saved === "left" || saved === "right")
|
|
@@ -5798,10 +6012,10 @@ function LiveAgent(props) {
|
|
|
5798
6012
|
} catch {}
|
|
5799
6013
|
}, []);
|
|
5800
6014
|
const savedLauncherBottom = readSavedLauncherBottom();
|
|
5801
|
-
const hasDraggedRef =
|
|
5802
|
-
const verticalAlignRef =
|
|
5803
|
-
const [launcherBottomPx, setLauncherBottomPxState] =
|
|
5804
|
-
const [popsDown, setPopsDown] =
|
|
6015
|
+
const hasDraggedRef = useRef18(savedLauncherBottom !== null);
|
|
6016
|
+
const verticalAlignRef = useRef18(verticalAlign);
|
|
6017
|
+
const [launcherBottomPx, setLauncherBottomPxState] = useState19(() => savedLauncherBottom !== null ? clampLauncherBottom(savedLauncherBottom) : verticalAlignToBottomPx(verticalAlign));
|
|
6018
|
+
const [popsDown, setPopsDown] = useState19(() => launcherPopsDown(launcherBottomPx));
|
|
5805
6019
|
const setLauncherBottomPx = useCallback15((px) => {
|
|
5806
6020
|
hasDraggedRef.current = true;
|
|
5807
6021
|
setLauncherBottomPxState(px);
|
|
@@ -5810,13 +6024,13 @@ function LiveAgent(props) {
|
|
|
5810
6024
|
localStorage.setItem("skippr_widget_bottom", String(px));
|
|
5811
6025
|
} catch {}
|
|
5812
6026
|
}, []);
|
|
5813
|
-
const launcherBottomPxRef =
|
|
6027
|
+
const launcherBottomPxRef = useRef18(launcherBottomPx);
|
|
5814
6028
|
launcherBottomPxRef.current = launcherBottomPx;
|
|
5815
6029
|
const commitLauncherDrop = useCallback15(({ side, bottomPx }) => {
|
|
5816
6030
|
setPositionWithPersist(side);
|
|
5817
6031
|
setLauncherBottomPx(bottomPx);
|
|
5818
6032
|
}, [setPositionWithPersist, setLauncherBottomPx]);
|
|
5819
|
-
|
|
6033
|
+
useEffect27(() => {
|
|
5820
6034
|
const syncToViewport = () => {
|
|
5821
6035
|
const next = hasDraggedRef.current ? clampLauncherBottom(launcherBottomPxRef.current) : verticalAlignToBottomPx(verticalAlignRef.current);
|
|
5822
6036
|
setLauncherBottomPxState(next);
|
|
@@ -5844,7 +6058,34 @@ function LiveAgent(props) {
|
|
|
5844
6058
|
minimizePanel();
|
|
5845
6059
|
}, [pauseSession, minimizePanel]);
|
|
5846
6060
|
const isAuthenticated = bearerToken !== null || auth.isAuthenticated;
|
|
5847
|
-
const
|
|
6061
|
+
const defaultAgentId = hostAgentId ?? defaultSelection.agentId;
|
|
6062
|
+
const startDefaultSession = useCallback15(() => {
|
|
6063
|
+
const target = availableModules.find((m) => m.id === defaultAgentId);
|
|
6064
|
+
if (!target)
|
|
6065
|
+
return;
|
|
6066
|
+
startSession({
|
|
6067
|
+
agentId: target.id,
|
|
6068
|
+
agentControls: target.controls,
|
|
6069
|
+
existingSessionId: defaultSelection.sessionId ?? undefined
|
|
6070
|
+
});
|
|
6071
|
+
}, [defaultAgentId, availableModules, defaultSelection.sessionId, startSession]);
|
|
6072
|
+
useAutoStart({ availableModules, isSessionLive, bearerToken, selectModule });
|
|
6073
|
+
const idleHistoryEnabled = !isSessionLive && !isPaused && isPanelOpen && isAuthenticated;
|
|
6074
|
+
const {
|
|
6075
|
+
messages: idleHistoryMessages,
|
|
6076
|
+
phases: idleHistoryPhases,
|
|
6077
|
+
isLoading: isLoadingHistory
|
|
6078
|
+
} = useSessionHistory({
|
|
6079
|
+
agentId: defaultAgentId ?? undefined,
|
|
6080
|
+
enabled: idleHistoryEnabled,
|
|
6081
|
+
authedFetch
|
|
6082
|
+
});
|
|
6083
|
+
const idleHistory = useMemo7(() => ({
|
|
6084
|
+
messages: idleHistoryMessages,
|
|
6085
|
+
phases: idleHistoryPhases,
|
|
6086
|
+
isLoading: isLoadingHistory
|
|
6087
|
+
}), [idleHistoryMessages, idleHistoryPhases, isLoadingHistory]);
|
|
6088
|
+
const ctx = useMemo7(() => ({
|
|
5848
6089
|
connection,
|
|
5849
6090
|
shouldConnect,
|
|
5850
6091
|
isConnected,
|
|
@@ -5861,6 +6102,7 @@ function LiveAgent(props) {
|
|
|
5861
6102
|
pauseTimeoutSeconds,
|
|
5862
6103
|
resumableSession,
|
|
5863
6104
|
historyMessages,
|
|
6105
|
+
idleHistory,
|
|
5864
6106
|
phasesSnapshot,
|
|
5865
6107
|
setPhasesSnapshot,
|
|
5866
6108
|
isPanelOpen,
|
|
@@ -5902,8 +6144,10 @@ function LiveAgent(props) {
|
|
|
5902
6144
|
agentId,
|
|
5903
6145
|
agentMode,
|
|
5904
6146
|
agentControls,
|
|
5905
|
-
displayModules,
|
|
6147
|
+
displayModules: availableModules,
|
|
5906
6148
|
activeModule,
|
|
6149
|
+
defaultAgentId,
|
|
6150
|
+
startDefaultSession,
|
|
5907
6151
|
isLoadingModules,
|
|
5908
6152
|
modulesError,
|
|
5909
6153
|
refetchModules,
|
|
@@ -5928,6 +6172,7 @@ function LiveAgent(props) {
|
|
|
5928
6172
|
pauseTimeoutSeconds,
|
|
5929
6173
|
resumableSession,
|
|
5930
6174
|
historyMessages,
|
|
6175
|
+
idleHistory,
|
|
5931
6176
|
phasesSnapshot,
|
|
5932
6177
|
isPanelOpen,
|
|
5933
6178
|
openPanel,
|
|
@@ -5964,8 +6209,10 @@ function LiveAgent(props) {
|
|
|
5964
6209
|
agentId,
|
|
5965
6210
|
agentMode,
|
|
5966
6211
|
agentControls,
|
|
5967
|
-
|
|
6212
|
+
availableModules,
|
|
5968
6213
|
activeModule,
|
|
6214
|
+
defaultAgentId,
|
|
6215
|
+
startDefaultSession,
|
|
5969
6216
|
isLoadingModules,
|
|
5970
6217
|
modulesError,
|
|
5971
6218
|
refetchModules,
|
|
@@ -5976,7 +6223,7 @@ function LiveAgent(props) {
|
|
|
5976
6223
|
]);
|
|
5977
6224
|
return /* @__PURE__ */ jsx22(LiveAgentContext.Provider, {
|
|
5978
6225
|
value: ctx,
|
|
5979
|
-
children: /* @__PURE__ */
|
|
6226
|
+
children: /* @__PURE__ */ jsxs18(LiveKitRoom, {
|
|
5980
6227
|
serverUrl: connection?.livekitUrl,
|
|
5981
6228
|
token: connection?.token,
|
|
5982
6229
|
connect: shouldConnect,
|
|
@@ -5988,7 +6235,7 @@ function LiveAgent(props) {
|
|
|
5988
6235
|
pendingScreenStream
|
|
5989
6236
|
}),
|
|
5990
6237
|
connection && captureMode === CAPTURE_MODE.Auto && /* @__PURE__ */ jsx22(DomCapture, {}),
|
|
5991
|
-
/* @__PURE__ */
|
|
6238
|
+
/* @__PURE__ */ jsxs18(ShadowHost, {
|
|
5992
6239
|
children: [
|
|
5993
6240
|
connection && captureMode === CAPTURE_MODE.Auto && agentControls?.highlight && /* @__PURE__ */ jsx22(HighlightOverlay, {}),
|
|
5994
6241
|
connection && captureMode === CAPTURE_MODE.Auto && agentControls?.actions && /* @__PURE__ */ jsx22(PageActionHandler, {}),
|
|
@@ -5996,22 +6243,24 @@ function LiveAgent(props) {
|
|
|
5996
6243
|
connection && captureMode === CAPTURE_MODE.Auto && (agentControls?.highlight || agentControls?.actions) && /* @__PURE__ */ jsx22(AgentCursorMount, {
|
|
5997
6244
|
animated: shouldAnimateCursor
|
|
5998
6245
|
}),
|
|
5999
|
-
/* @__PURE__ */
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6246
|
+
/* @__PURE__ */ jsx22(SessionHoldProvider, {
|
|
6247
|
+
children: /* @__PURE__ */ jsxs18("div", {
|
|
6248
|
+
id: WIDGET_ROOT_ID,
|
|
6249
|
+
children: [
|
|
6250
|
+
isMinimized && !showControlBar && /* @__PURE__ */ jsx22(MinimizedBubble, {
|
|
6251
|
+
welcomeMessage,
|
|
6252
|
+
welcomeDismissed,
|
|
6253
|
+
onDismissWelcome: dismissWelcome
|
|
6254
|
+
}),
|
|
6255
|
+
showControlBar && !hideControls && /* @__PURE__ */ jsx22(SessionControlBar, {}),
|
|
6256
|
+
/* @__PURE__ */ jsx22(SidebarTrigger, {}),
|
|
6257
|
+
/* @__PURE__ */ jsx22(Sidebar, {
|
|
6258
|
+
hideControls,
|
|
6259
|
+
hideHeader,
|
|
6260
|
+
startSessionLabel
|
|
6261
|
+
})
|
|
6262
|
+
]
|
|
6263
|
+
})
|
|
6015
6264
|
})
|
|
6016
6265
|
]
|
|
6017
6266
|
}),
|