@skippr/live-agent-sdk 0.121.0 → 0.123.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.
@@ -586,6 +586,7 @@ var PENDING_START_KIND = {
586
586
  var PLAN_ATTR = "skippr.action-plan";
587
587
  var LINK_CARD_ATTR = "skippr.link-card";
588
588
  var NAME_MAX_CHARS = 80;
589
+ var TIP_DEEPLINK_PARAM = "skippr";
589
590
 
590
591
  // src/components/ConsentNotice.tsx
591
592
  import { jsx } from "react/jsx-runtime";
@@ -4911,31 +4912,40 @@ function useAdoptionGoals({
4911
4912
  authedFetch
4912
4913
  }) {
4913
4914
  const [candidates, setCandidates] = useState11([]);
4915
+ const [deepLinkedGoal, setDeepLinkedGoal] = useState11(null);
4914
4916
  const [hasResolved, setHasResolved] = useState11(false);
4915
4917
  const [hash, setHash] = useState11(window.location.hash);
4918
+ const [tipSlug] = useState11(() => new URLSearchParams(window.location.search).get(TIP_DEEPLINK_PARAM) || null);
4916
4919
  const match = useCallback11(async () => {
4917
4920
  try {
4918
4921
  const resp = await authedFetch(`${API_URL}/v1/adoption/goals/match`, {
4919
4922
  method: "POST",
4920
4923
  headers: { "Content-Type": "application/json" },
4921
- body: JSON.stringify({ url: window.location.origin + window.location.pathname })
4924
+ body: JSON.stringify({
4925
+ url: window.location.origin + window.location.pathname,
4926
+ ...tipSlug ? { tipSlug } : {}
4927
+ })
4922
4928
  });
4923
4929
  if (!resp.ok) {
4924
4930
  setCandidates([]);
4931
+ setDeepLinkedGoal(null);
4925
4932
  return;
4926
4933
  }
4927
4934
  const data = await resp.json();
4928
4935
  setCandidates(Array.isArray(data?.goals) ? data.goals : []);
4936
+ setDeepLinkedGoal(data?.deepLinkedGoal ?? null);
4929
4937
  } catch (e) {
4930
4938
  console.warn("[Skippr] adoption match failed", e);
4931
4939
  setCandidates([]);
4940
+ setDeepLinkedGoal(null);
4932
4941
  } finally {
4933
4942
  setHasResolved(true);
4934
4943
  }
4935
- }, [authedFetch]);
4944
+ }, [authedFetch, tipSlug]);
4936
4945
  useEffect13(() => {
4937
4946
  if (!enabled || !bearerToken) {
4938
4947
  setCandidates([]);
4948
+ setDeepLinkedGoal(null);
4939
4949
  setHasResolved(false);
4940
4950
  return;
4941
4951
  }
@@ -4976,7 +4986,7 @@ function useAdoptionGoals({
4976
4986
  const attendGoal = useCallback11((goalId) => {
4977
4987
  postStatus(goalId, "attended" /* Attended */);
4978
4988
  }, [postStatus]);
4979
- return { goals, hasResolved, attendGoal };
4989
+ return { goals, deepLinkedGoal, hasTipSlug: tipSlug !== null, hasResolved, attendGoal };
4980
4990
  }
4981
4991
 
4982
4992
  // src/hooks/useAuth.ts
@@ -5224,22 +5234,35 @@ async function isMicGranted() {
5224
5234
  }
5225
5235
  function useAutoStart({
5226
5236
  availableModules,
5237
+ deepLinkedGoal,
5238
+ hasTipSlug,
5239
+ adoptionResolved,
5227
5240
  suppressed,
5241
+ moduleSuppressed,
5242
+ modulesResolved,
5228
5243
  bearerToken,
5229
- selectModule
5244
+ selectModule,
5245
+ startAdoptionSession
5230
5246
  }) {
5231
5247
  const hasAutoStartedRef = useRef12(false);
5248
+ const hasGesturedRef = useRef12(false);
5232
5249
  const autoStartModule = useMemo3(() => availableModules.find((m) => {
5233
5250
  if (!m.uiPreferences?.autoStart)
5234
5251
  return false;
5235
5252
  const state = getModuleSessionState(m.currentSession, m.mode);
5236
5253
  return state !== "completed" && state !== "expired";
5237
5254
  }) ?? null, [availableModules]);
5255
+ const awaitingDeepLink = hasTipSlug && !adoptionResolved;
5256
+ const moduleTarget = moduleSuppressed || awaitingDeepLink ? null : autoStartModule;
5238
5257
  useEffect15(() => {
5239
- if (!autoStartModule || hasAutoStartedRef.current)
5258
+ if (hasAutoStartedRef.current)
5240
5259
  return;
5241
5260
  if (suppressed || !bearerToken)
5242
5261
  return;
5262
+ if (!modulesResolved)
5263
+ return;
5264
+ if (!deepLinkedGoal && !moduleTarget && !awaitingDeepLink)
5265
+ return;
5243
5266
  let cancelled = false;
5244
5267
  const stopWaitingForGesture = () => {
5245
5268
  document.removeEventListener("pointerdown", onFirstGesture, true);
@@ -5248,13 +5271,22 @@ function useAutoStart({
5248
5271
  const startOnce = () => {
5249
5272
  if (cancelled || hasAutoStartedRef.current)
5250
5273
  return;
5274
+ if (!deepLinkedGoal && !moduleTarget) {
5275
+ hasGesturedRef.current = true;
5276
+ return;
5277
+ }
5251
5278
  hasAutoStartedRef.current = true;
5252
5279
  stopWaitingForGesture();
5253
- selectModule(autoStartModule.id, { autoStarted: true });
5280
+ if (deepLinkedGoal)
5281
+ startAdoptionSession(deepLinkedGoal);
5282
+ else if (moduleTarget)
5283
+ selectModule(moduleTarget.id, { autoStarted: true });
5254
5284
  };
5255
5285
  const onFirstGesture = () => startOnce();
5256
5286
  document.addEventListener("pointerdown", onFirstGesture, true);
5257
5287
  document.addEventListener("keydown", onFirstGesture, true);
5288
+ if (hasGesturedRef.current)
5289
+ startOnce();
5258
5290
  isMicGranted().then((granted) => {
5259
5291
  if (granted)
5260
5292
  startOnce();
@@ -5263,7 +5295,16 @@ function useAutoStart({
5263
5295
  cancelled = true;
5264
5296
  stopWaitingForGesture();
5265
5297
  };
5266
- }, [autoStartModule, suppressed, bearerToken, selectModule]);
5298
+ }, [
5299
+ moduleTarget,
5300
+ deepLinkedGoal,
5301
+ awaitingDeepLink,
5302
+ suppressed,
5303
+ modulesResolved,
5304
+ bearerToken,
5305
+ selectModule,
5306
+ startAdoptionSession
5307
+ ]);
5267
5308
  }
5268
5309
 
5269
5310
  // src/hooks/useAvailableModules.ts
@@ -5467,7 +5508,7 @@ function usePlanUpdates() {
5467
5508
  // src/hooks/useSession.ts
5468
5509
  import { useCallback as useCallback15, useEffect as useEffect20, useRef as useRef15, useState as useState17 } from "react";
5469
5510
  var API_URL4 = "https://app.skippr.ai/api";
5470
- var SDK_VERSION = "0.121.0";
5511
+ var SDK_VERSION = "0.123.0";
5471
5512
  async function fetchSessionMessages(sessionId, authedFetch) {
5472
5513
  try {
5473
5514
  const resp = await authedFetch(`${API_URL4}/v1/sessions/${sessionId}/messages`);
@@ -12129,7 +12170,11 @@ function SplashAlwaysOn({
12129
12170
  onClick: start,
12130
12171
  className: `${FOCUS_RING3} skippr:flex skippr:w-full skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:gap-2 skippr:rounded-full skippr:bg-primary skippr:px-5 skippr:py-[13px] skippr:text-[16px] skippr:font-semibold skippr:text-primary-foreground skippr:transition-all skippr:hover:bg-primary/90`,
12131
12172
  children: [
12132
- /* @__PURE__ */ jsx44(Sparkles, {
12173
+ headerIconUrl ? /* @__PURE__ */ jsx44("img", {
12174
+ src: headerIconUrl,
12175
+ alt: "",
12176
+ className: "skippr:size-4 skippr:object-contain"
12177
+ }) : /* @__PURE__ */ jsx44(Sparkles, {
12133
12178
  className: "skippr:size-4",
12134
12179
  strokeWidth: ROW_ICON_STROKE,
12135
12180
  "aria-hidden": true
@@ -12392,7 +12437,11 @@ function SplashPrimary({
12392
12437
  onClick: start,
12393
12438
  className: `${FOCUS_RING3} skippr:flex skippr:w-full skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:gap-2 skippr:rounded-full skippr:bg-primary skippr:px-5 skippr:py-[13px] skippr:text-[16px] skippr:font-semibold skippr:text-primary-foreground skippr:transition-all skippr:hover:bg-primary/90`,
12394
12439
  children: [
12395
- /* @__PURE__ */ jsx45(Sparkles, {
12440
+ headerIconUrl ? /* @__PURE__ */ jsx45("img", {
12441
+ src: headerIconUrl,
12442
+ alt: "",
12443
+ className: "skippr:size-4 skippr:object-contain"
12444
+ }) : /* @__PURE__ */ jsx45(Sparkles, {
12396
12445
  className: "skippr:size-4",
12397
12446
  strokeWidth: ROW_ICON_STROKE,
12398
12447
  "aria-hidden": true
@@ -14762,6 +14811,8 @@ function LiveAgent(props) {
14762
14811
  const isLauncherRevealed = useOnceTrue(!isAwaitingModules);
14763
14812
  const {
14764
14813
  goals: adoptionGoals,
14814
+ deepLinkedGoal,
14815
+ hasTipSlug,
14765
14816
  hasResolved: hasResolvedAdoptionGoals,
14766
14817
  attendGoal
14767
14818
  } = useAdoptionGoals({
@@ -15012,9 +15063,15 @@ function LiveAgent(props) {
15012
15063
  }, [pendingStart, startAdoptionSession, selectModule, startDefaultSession]);
15013
15064
  useAutoStart({
15014
15065
  availableModules,
15015
- suppressed: isSessionLive || buddyActive,
15066
+ deepLinkedGoal,
15067
+ hasTipSlug,
15068
+ adoptionResolved: hasResolvedAdoptionGoals,
15069
+ suppressed: isSessionLive,
15070
+ moduleSuppressed: buddyActive,
15071
+ modulesResolved: hasResolvedModules,
15016
15072
  bearerToken,
15017
- selectModule
15073
+ selectModule,
15074
+ startAdoptionSession
15018
15075
  });
15019
15076
  useEffect51(() => {
15020
15077
  if (!autoStartAfterLogin)