@usecrow/ui 0.1.75 → 0.1.76

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/index.js CHANGED
@@ -48,6 +48,8 @@ function useChat({
48
48
  subdomain,
49
49
  toolConsentSettings,
50
50
  language,
51
+ agentMode,
52
+ onOnboardingComplete,
51
53
  onVerificationStatus,
52
54
  onConversationId,
53
55
  onWorkflowEvent,
@@ -140,7 +142,8 @@ function useChat({
140
142
  user_local_time: (/* @__PURE__ */ new Date()).toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric", hour12: true }),
141
143
  page_path: typeof window !== "undefined" ? window.location.pathname : void 0,
142
144
  context: typeof window !== "undefined" ? window.__crow_page_context : void 0,
143
- ...language && language !== "en" ? { language } : {}
145
+ ...language && language !== "en" ? { language } : {},
146
+ ...agentMode ? { agent_mode: agentMode } : {}
144
147
  }),
145
148
  signal: abortControllerRef.current.signal
146
149
  });
@@ -468,6 +471,9 @@ function useChat({
468
471
  setSuggestedActions(parsed.actions);
469
472
  }
470
473
  break;
474
+ case "onboarding_complete":
475
+ onOnboardingComplete?.(parsed.summary || "");
476
+ break;
471
477
  }
472
478
  } catch (e) {
473
479
  console.error("[Crow] Parse error:", e);
@@ -500,7 +506,7 @@ function useChat({
500
506
  abortControllerRef.current = null;
501
507
  }
502
508
  },
503
- [apiUrl, productId, conversationId, selectedModel, subdomain, persistAnonymousConversations, onVerificationStatus, onConversationId, onWorkflowEvent, onToolCall, onToolResult]
509
+ [apiUrl, productId, conversationId, selectedModel, subdomain, persistAnonymousConversations, agentMode, onOnboardingComplete, onVerificationStatus, onConversationId, onWorkflowEvent, onToolCall, onToolResult]
504
510
  );
505
511
  const sendMessage = useCallback(
506
512
  (content) => {
@@ -1670,6 +1676,18 @@ function useWidgetStyles({
1670
1676
  const [availableModels, setAvailableModels] = useState(
1671
1677
  styleCache.get(key)?.availableModels || []
1672
1678
  );
1679
+ const [onboardingEnabled, setOnboardingEnabled] = useState(
1680
+ styleCache.get(key)?.onboardingEnabled || false
1681
+ );
1682
+ const [onboardingAgentName, setOnboardingAgentName] = useState(
1683
+ styleCache.get(key)?.onboardingAgentName ?? void 0
1684
+ );
1685
+ const [onboardingWelcomeMessage, setOnboardingWelcomeMessage] = useState(
1686
+ styleCache.get(key)?.onboardingWelcomeMessage ?? void 0
1687
+ );
1688
+ const [onboardingIntroSequence, setOnboardingIntroSequence] = useState(
1689
+ styleCache.get(key)?.onboardingIntroSequence ?? void 0
1690
+ );
1673
1691
  const hasFetchedRef = useRef(false);
1674
1692
  const fetchStyles = async () => {
1675
1693
  if (skip) return;
@@ -1691,6 +1709,10 @@ function useWidgetStyles({
1691
1709
  setToolConsentSettings(config.toolConsentSettings || {});
1692
1710
  setModelSelectionEnabled(config.modelSelectionEnabled || false);
1693
1711
  setAvailableModels(config.availableModels || []);
1712
+ setOnboardingEnabled(config.onboardingEnabled || false);
1713
+ setOnboardingAgentName(config.onboardingAgentName ?? void 0);
1714
+ setOnboardingWelcomeMessage(config.onboardingWelcomeMessage ?? void 0);
1715
+ setOnboardingIntroSequence(config.onboardingIntroSequence ?? void 0);
1694
1716
  } catch (err) {
1695
1717
  console.error("[CrowWidget] Failed to fetch styles:", err);
1696
1718
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -1734,6 +1756,10 @@ function useWidgetStyles({
1734
1756
  toolConsentSettings,
1735
1757
  modelSelectionEnabled,
1736
1758
  availableModels,
1759
+ onboardingEnabled,
1760
+ onboardingAgentName,
1761
+ onboardingWelcomeMessage,
1762
+ onboardingIntroSequence,
1737
1763
  refetch: fetchStyles
1738
1764
  };
1739
1765
  }
@@ -1782,6 +1808,18 @@ function useCopilotStyles({
1782
1808
  const [initialSuggestions, setInitialSuggestions] = useState(
1783
1809
  styleCache.get(key)?.initialSuggestions || []
1784
1810
  );
1811
+ const [onboardingEnabled, setOnboardingEnabled] = useState(
1812
+ styleCache.get(key)?.onboardingEnabled || false
1813
+ );
1814
+ const [onboardingAgentName, setOnboardingAgentName] = useState(
1815
+ styleCache.get(key)?.onboardingAgentName ?? void 0
1816
+ );
1817
+ const [onboardingWelcomeMessage, setOnboardingWelcomeMessage] = useState(
1818
+ styleCache.get(key)?.onboardingWelcomeMessage ?? void 0
1819
+ );
1820
+ const [onboardingIntroSequence, setOnboardingIntroSequence] = useState(
1821
+ styleCache.get(key)?.onboardingIntroSequence ?? void 0
1822
+ );
1785
1823
  const hasFetchedRef = useRef(false);
1786
1824
  const fetchStyles = async () => {
1787
1825
  if (skip) return;
@@ -1802,6 +1840,10 @@ function useCopilotStyles({
1802
1840
  setModelSelectionEnabled(config.modelSelectionEnabled || false);
1803
1841
  setAvailableModels(config.availableModels || []);
1804
1842
  setInitialSuggestions(config.initialSuggestions || []);
1843
+ setOnboardingEnabled(config.onboardingEnabled || false);
1844
+ setOnboardingAgentName(config.onboardingAgentName ?? void 0);
1845
+ setOnboardingWelcomeMessage(config.onboardingWelcomeMessage ?? void 0);
1846
+ setOnboardingIntroSequence(config.onboardingIntroSequence ?? void 0);
1805
1847
  } catch (err) {
1806
1848
  console.error("[CrowCopilot] Failed to fetch styles:", err);
1807
1849
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -1824,6 +1866,10 @@ function useCopilotStyles({
1824
1866
  setModelSelectionEnabled(cached.modelSelectionEnabled || false);
1825
1867
  setAvailableModels(cached.availableModels || []);
1826
1868
  setInitialSuggestions(cached.initialSuggestions || []);
1869
+ setOnboardingEnabled(cached.onboardingEnabled || false);
1870
+ setOnboardingAgentName(cached.onboardingAgentName ?? void 0);
1871
+ setOnboardingWelcomeMessage(cached.onboardingWelcomeMessage ?? void 0);
1872
+ setOnboardingIntroSequence(cached.onboardingIntroSequence ?? void 0);
1827
1873
  setIsLoading(false);
1828
1874
  return;
1829
1875
  }
@@ -1846,6 +1892,10 @@ function useCopilotStyles({
1846
1892
  modelSelectionEnabled,
1847
1893
  availableModels,
1848
1894
  initialSuggestions,
1895
+ onboardingEnabled,
1896
+ onboardingAgentName,
1897
+ onboardingWelcomeMessage,
1898
+ onboardingIntroSequence,
1849
1899
  refetch: fetchStyles
1850
1900
  };
1851
1901
  }
@@ -4504,6 +4554,84 @@ function injectStyles(target = document) {
4504
4554
  target.prepend(style);
4505
4555
  }
4506
4556
  }
4557
+ function OnboardingIntroInline({
4558
+ lines,
4559
+ primaryColor,
4560
+ onComplete
4561
+ }) {
4562
+ const [lineIndex, setLineIndex] = useState(0);
4563
+ const [charIndex, setCharIndex] = useState(0);
4564
+ const [done, setDone] = useState(false);
4565
+ useEffect(() => {
4566
+ if (lineIndex >= lines.length) {
4567
+ setDone(true);
4568
+ return;
4569
+ }
4570
+ const currentLine = lines[lineIndex];
4571
+ if (charIndex < currentLine.length) {
4572
+ const t = setTimeout(() => setCharIndex((c) => c + 1), 35);
4573
+ return () => clearTimeout(t);
4574
+ } else {
4575
+ const t = setTimeout(() => {
4576
+ setLineIndex((l) => l + 1);
4577
+ setCharIndex(0);
4578
+ }, 500);
4579
+ return () => clearTimeout(t);
4580
+ }
4581
+ }, [lineIndex, charIndex, lines]);
4582
+ const displayedLines = lines.slice(0, lineIndex + 1).map(
4583
+ (line, i) => i < lineIndex ? line : line.slice(0, charIndex)
4584
+ );
4585
+ return /* @__PURE__ */ jsxs("div", { style: {
4586
+ display: "flex",
4587
+ flexDirection: "column",
4588
+ alignItems: "center",
4589
+ justifyContent: "center",
4590
+ flex: 1,
4591
+ padding: "24px 16px",
4592
+ textAlign: "center"
4593
+ }, children: [
4594
+ /* @__PURE__ */ jsx("div", { style: { minHeight: "4rem", marginBottom: "1.5rem" }, children: displayedLines.map((text, i) => /* @__PURE__ */ jsxs("p", { style: {
4595
+ fontSize: i === 0 ? 18 : 14,
4596
+ fontWeight: i === 0 ? 600 : 400,
4597
+ color: i === 0 ? "var(--crow-text, #111827)" : "var(--crow-text-secondary, #6b7280)",
4598
+ lineHeight: 1.4,
4599
+ margin: "0 0 6px 0"
4600
+ }, children: [
4601
+ text,
4602
+ i === lineIndex && !done && /* @__PURE__ */ jsx("span", { style: {
4603
+ display: "inline-block",
4604
+ width: 2,
4605
+ height: i === 0 ? 18 : 14,
4606
+ backgroundColor: "var(--crow-text, #111827)",
4607
+ marginLeft: 2,
4608
+ verticalAlign: "middle",
4609
+ animation: "crow-blink 1s step-end infinite"
4610
+ } })
4611
+ ] }, i)) }),
4612
+ /* @__PURE__ */ jsx(
4613
+ "button",
4614
+ {
4615
+ onClick: onComplete,
4616
+ style: {
4617
+ padding: "8px 24px",
4618
+ borderRadius: 8,
4619
+ backgroundColor: primaryColor,
4620
+ color: "#fff",
4621
+ fontSize: 13,
4622
+ fontWeight: 500,
4623
+ border: "none",
4624
+ cursor: "pointer",
4625
+ opacity: done ? 1 : 0,
4626
+ pointerEvents: done ? "auto" : "none",
4627
+ transition: "opacity 0.5s ease"
4628
+ },
4629
+ children: "Get Started \u2192"
4630
+ }
4631
+ ),
4632
+ /* @__PURE__ */ jsx("style", { children: `@keyframes crow-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }` })
4633
+ ] });
4634
+ }
4507
4635
  function CrowWidget({
4508
4636
  productId,
4509
4637
  apiUrl = "",
@@ -4524,7 +4652,9 @@ function CrowWidget({
4524
4652
  toolRenderers,
4525
4653
  language,
4526
4654
  customCss,
4527
- contextLabel: contextLabelProp
4655
+ contextLabel: contextLabelProp,
4656
+ forceOnboarding = false,
4657
+ fullscreenTopOffset: _fullscreenTopOffset = 0
4528
4658
  }) {
4529
4659
  const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
4530
4660
  const effectiveOnToolResult = onToolResult || window.__crow_on_tool_result;
@@ -4543,7 +4673,11 @@ function CrowWidget({
4543
4673
  initialSuggestions,
4544
4674
  toolConsentSettings,
4545
4675
  modelSelectionEnabled,
4546
- availableModels: availableModelsFromAPI
4676
+ availableModels: availableModelsFromAPI,
4677
+ onboardingEnabled,
4678
+ onboardingAgentName,
4679
+ onboardingWelcomeMessage,
4680
+ onboardingIntroSequence
4547
4681
  } = useWidgetStyles({
4548
4682
  productId,
4549
4683
  apiUrl,
@@ -4580,6 +4714,25 @@ function CrowWidget({
4580
4714
  const welcomeMessage = greetingOverride ?? welcomeMessageProp ?? welcomeMessageFromAPI;
4581
4715
  const selectedModel = selectedModelFromAPI;
4582
4716
  const showThinking = showThinkingProp ?? showThinkingFromAPI;
4717
+ const [isOnboarding, setIsOnboarding] = useState(false);
4718
+ const [onboardingChecked, setOnboardingChecked] = useState(false);
4719
+ const [onboardingPhase, setOnboardingPhase] = useState("intro");
4720
+ useEffect(() => {
4721
+ if (forceOnboarding && !isLoadingStyles && onboardingEnabled && !onboardingChecked) {
4722
+ setIsOnboarding(true);
4723
+ setOnboardingChecked(true);
4724
+ }
4725
+ }, [forceOnboarding, isLoadingStyles, onboardingEnabled, onboardingChecked]);
4726
+ useEffect(() => {
4727
+ if (isOnboarding) {
4728
+ setIsCollapsed(false);
4729
+ }
4730
+ }, [isOnboarding]);
4731
+ useEffect(() => {
4732
+ if (isOnboarding && !isLoadingStyles && onboardingIntroSequence !== void 0 && onboardingIntroSequence.length === 0) {
4733
+ setOnboardingPhase("chat");
4734
+ }
4735
+ }, [isOnboarding, isLoadingStyles, onboardingIntroSequence]);
4583
4736
  const [autoTools, setAutoTools] = useState({});
4584
4737
  const cssVars = stylesToCssVars(styles);
4585
4738
  const transform = useWidgetTransform({
@@ -4629,11 +4782,17 @@ function CrowWidget({
4629
4782
  const conversations = useConversations({ productId, apiUrl });
4630
4783
  const [shouldRestoreHistory, setShouldRestoreHistory] = useState(false);
4631
4784
  const hasRestoredHistoryRef = useRef(false);
4785
+ const effectiveWelcomeMessage = isOnboarding ? onboardingWelcomeMessage || `Hi! I'm ${onboardingAgentName || agentName}. Let me help you get started.` : welcomeMessage;
4632
4786
  const chat = useChat({
4633
4787
  productId,
4634
4788
  apiUrl,
4635
4789
  persistAnonymousConversations,
4636
- welcomeMessage,
4790
+ welcomeMessage: effectiveWelcomeMessage,
4791
+ agentMode: isOnboarding ? "onboarding" : void 0,
4792
+ onOnboardingComplete: (summary) => {
4793
+ console.log("[Crow] Onboarding complete:", summary);
4794
+ setIsOnboarding(false);
4795
+ },
4637
4796
  selectedModel,
4638
4797
  subdomain,
4639
4798
  toolConsentSettings,
@@ -4721,10 +4880,10 @@ function CrowWidget({
4721
4880
  wasLoadingRef.current = chat.isLoading;
4722
4881
  }, [chat.isLoading, chat.messages]);
4723
4882
  useEffect(() => {
4724
- if (initialSuggestions.length > 0 && chat.suggestedActions.length === 0) {
4883
+ if (!isOnboarding && initialSuggestions.length > 0 && chat.suggestedActions.length === 0) {
4725
4884
  chat.setSuggestedActions(initialSuggestions);
4726
4885
  }
4727
- }, [initialSuggestions]);
4886
+ }, [initialSuggestions, isOnboarding]);
4728
4887
  useEffect(() => {
4729
4888
  if (shouldRestoreHistory && chat.conversationId && !hasRestoredHistoryRef.current) {
4730
4889
  hasRestoredHistoryRef.current = true;
@@ -4759,6 +4918,33 @@ function CrowWidget({
4759
4918
  const { executeClientTool } = useCrowAPI({
4760
4919
  onIdentified: async () => {
4761
4920
  setIsVerifiedUser(true);
4921
+ if (forceOnboarding) {
4922
+ setIsOnboarding(true);
4923
+ setOnboardingChecked(true);
4924
+ } else if (onboardingEnabled && !onboardingChecked) {
4925
+ try {
4926
+ const identityToken = window.__crow_identity_token;
4927
+ if (identityToken) {
4928
+ const res = await fetch(`${apiUrl}/api/chat/resolve-agent`, {
4929
+ method: "POST",
4930
+ headers: { "Content-Type": "application/json" },
4931
+ body: JSON.stringify({
4932
+ product_id: productId,
4933
+ identity_token: identityToken
4934
+ })
4935
+ });
4936
+ if (res.ok) {
4937
+ const data = await res.json();
4938
+ if (data.agent === "onboarding") {
4939
+ setIsOnboarding(true);
4940
+ }
4941
+ }
4942
+ }
4943
+ } catch (e) {
4944
+ console.error("[Crow] resolve-agent failed:", e);
4945
+ }
4946
+ setOnboardingChecked(true);
4947
+ }
4762
4948
  const convs = await conversations.loadConversations();
4763
4949
  if (convs.length > 0) {
4764
4950
  const mostRecent = convs[0];
@@ -4776,6 +4962,16 @@ function CrowWidget({
4776
4962
  });
4777
4963
  executeClientToolRef.current = executeClientTool;
4778
4964
  submitToolResultRef.current = chat.submitToolResult;
4965
+ const prevOnboardingRef = useRef(isOnboarding);
4966
+ useEffect(() => {
4967
+ if (isOnboarding && !prevOnboardingRef.current) {
4968
+ chat.setSuggestedActions([]);
4969
+ }
4970
+ if (prevOnboardingRef.current && !isOnboarding) {
4971
+ chat.resetMessages();
4972
+ }
4973
+ prevOnboardingRef.current = isOnboarding;
4974
+ }, [isOnboarding]);
4779
4975
  useEffect(() => {
4780
4976
  if (!isLoadingStyles) {
4781
4977
  onReady?.();
@@ -5060,7 +5256,59 @@ function CrowWidget({
5060
5256
  setIsCollapsed(!isCollapsed);
5061
5257
  };
5062
5258
  const renderWidgetContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
5063
- /* @__PURE__ */ jsx(
5259
+ isOnboarding ? /* @__PURE__ */ jsxs(
5260
+ "div",
5261
+ {
5262
+ style: {
5263
+ display: "flex",
5264
+ alignItems: "center",
5265
+ justifyContent: "space-between",
5266
+ padding: "10px 16px",
5267
+ borderBottom: "1px solid var(--crow-border, #e5e7eb)",
5268
+ flexShrink: 0,
5269
+ cursor: variant === "floating" ? "grab" : void 0
5270
+ },
5271
+ onPointerDown: variant === "floating" ? transform.onDragPointerDown : void 0,
5272
+ children: [
5273
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "var(--crow-text, #111827)" }, children: onboardingAgentName || agentName }),
5274
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
5275
+ /* @__PURE__ */ jsx(
5276
+ "button",
5277
+ {
5278
+ onClick: () => {
5279
+ setIsOnboarding(false);
5280
+ chat.resetMessages();
5281
+ },
5282
+ style: {
5283
+ fontSize: 12,
5284
+ color: "#9ca3af",
5285
+ background: "none",
5286
+ border: "none",
5287
+ cursor: "pointer",
5288
+ padding: "4px 8px"
5289
+ },
5290
+ children: "Skip"
5291
+ }
5292
+ ),
5293
+ variant === "floating" && /* @__PURE__ */ jsx(
5294
+ "button",
5295
+ {
5296
+ onClick: () => setIsCollapsed(true),
5297
+ style: {
5298
+ background: "none",
5299
+ border: "none",
5300
+ cursor: "pointer",
5301
+ padding: "4px",
5302
+ color: "#9ca3af",
5303
+ display: "flex"
5304
+ },
5305
+ children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M6 18L18 6M6 6l12 12" }) })
5306
+ }
5307
+ )
5308
+ ] })
5309
+ ]
5310
+ }
5311
+ ) : /* @__PURE__ */ jsx(
5064
5312
  WidgetHeader,
5065
5313
  {
5066
5314
  isVerifiedUser,
@@ -5076,82 +5324,92 @@ function CrowWidget({
5076
5324
  contextLabel
5077
5325
  }
5078
5326
  ),
5079
- /* @__PURE__ */ jsx(AnimatePresence, { children: showConversationList && isVerifiedUser && /* @__PURE__ */ jsx(
5080
- ConversationList,
5081
- {
5082
- conversations: conversations.conversations,
5083
- currentConversationId: chat.conversationId,
5084
- onSelect: handleSelectConversation,
5085
- onClose: handleCloseConversationList
5086
- }
5087
- ) }),
5088
- /* @__PURE__ */ jsx(AnimatePresence, { children: activeWorkflow && /* @__PURE__ */ jsx(
5089
- WorkflowPanel,
5327
+ isOnboarding && onboardingPhase === "intro" && /* @__PURE__ */ jsx(
5328
+ OnboardingIntroInline,
5090
5329
  {
5091
- workflow: activeWorkflow,
5092
- onExit: handleExitWorkflow
5330
+ lines: onboardingIntroSequence || [],
5331
+ primaryColor: styles.colors.primary,
5332
+ onComplete: () => setOnboardingPhase("chat")
5093
5333
  }
5094
- ) }),
5095
- /* @__PURE__ */ jsx(AnimatePresence, { children: (chat.messages.length > 0 || conversations.isLoadingHistory || pendingConfirmation) && /* @__PURE__ */ jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
5096
- /* @__PURE__ */ jsx(
5097
- MessageList,
5334
+ ),
5335
+ !(isOnboarding && onboardingPhase === "intro") && /* @__PURE__ */ jsxs(Fragment, { children: [
5336
+ /* @__PURE__ */ jsx(AnimatePresence, { children: showConversationList && isVerifiedUser && /* @__PURE__ */ jsx(
5337
+ ConversationList,
5098
5338
  {
5099
- messages: chat.messages,
5100
- activeToolCalls: chat.activeToolCalls,
5101
- isLoadingHistory: conversations.isLoadingHistory,
5102
- isGenerating: chat.isLoading,
5103
- toolRenderers: effectiveToolRenderers,
5104
- onToolConsent: handleToolConsent
5339
+ conversations: conversations.conversations,
5340
+ currentConversationId: chat.conversationId,
5341
+ onSelect: handleSelectConversation,
5342
+ onClose: handleCloseConversationList
5105
5343
  }
5106
- ),
5107
- pendingConfirmation && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
5108
- BrowserUseConfirmation,
5344
+ ) }),
5345
+ /* @__PURE__ */ jsx(AnimatePresence, { children: activeWorkflow && /* @__PURE__ */ jsx(
5346
+ WorkflowPanel,
5109
5347
  {
5110
- instruction: pendingConfirmation.instruction,
5111
- onAllow: () => {
5112
- setIsBrowserUseActive(true);
5113
- pendingConfirmation.resolve(true);
5114
- setPendingConfirmation(null);
5115
- },
5116
- onDeny: () => {
5117
- pendingConfirmation.resolve(false);
5118
- setPendingConfirmation(null);
5119
- }
5348
+ workflow: activeWorkflow,
5349
+ onExit: handleExitWorkflow
5120
5350
  }
5121
- ) })
5122
- ] }) }),
5123
- /* @__PURE__ */ jsxs("div", { className: "crow-mt-auto crow-w-full", children: [
5124
- toolStatus && /* @__PURE__ */ jsxs("div", { className: "crow-mx-3 crow-mb-1 crow-flex crow-items-center crow-gap-2 crow-rounded-lg crow-border crow-border-[var(--crow-border,#e5e7eb)] crow-bg-[var(--crow-bg-secondary,#f3f4f6)] crow-px-3 crow-py-2 crow-text-sm", children: [
5125
- /* @__PURE__ */ jsxs("svg", { className: "crow-animate-spin crow-h-4 crow-w-4 crow-shrink-0 crow-text-[var(--crow-primary,#7c3aed)]", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
5126
- /* @__PURE__ */ jsx("circle", { className: "crow-opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5127
- /* @__PURE__ */ jsx("path", { className: "crow-opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
5351
+ ) }),
5352
+ /* @__PURE__ */ jsx(AnimatePresence, { children: (chat.messages.length > 0 || conversations.isLoadingHistory || pendingConfirmation) && /* @__PURE__ */ jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
5353
+ /* @__PURE__ */ jsx(
5354
+ MessageList,
5355
+ {
5356
+ messages: chat.messages,
5357
+ activeToolCalls: chat.activeToolCalls,
5358
+ isLoadingHistory: conversations.isLoadingHistory,
5359
+ isGenerating: chat.isLoading,
5360
+ toolRenderers: effectiveToolRenderers,
5361
+ onToolConsent: handleToolConsent
5362
+ }
5363
+ ),
5364
+ pendingConfirmation && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
5365
+ BrowserUseConfirmation,
5366
+ {
5367
+ instruction: pendingConfirmation.instruction,
5368
+ onAllow: () => {
5369
+ setIsBrowserUseActive(true);
5370
+ pendingConfirmation.resolve(true);
5371
+ setPendingConfirmation(null);
5372
+ },
5373
+ onDeny: () => {
5374
+ pendingConfirmation.resolve(false);
5375
+ setPendingConfirmation(null);
5376
+ }
5377
+ }
5378
+ ) })
5379
+ ] }) }),
5380
+ /* @__PURE__ */ jsxs("div", { className: "crow-mt-auto crow-w-full", children: [
5381
+ toolStatus && /* @__PURE__ */ jsxs("div", { className: "crow-mx-3 crow-mb-1 crow-flex crow-items-center crow-gap-2 crow-rounded-lg crow-border crow-border-[var(--crow-border,#e5e7eb)] crow-bg-[var(--crow-bg-secondary,#f3f4f6)] crow-px-3 crow-py-2 crow-text-sm", children: [
5382
+ /* @__PURE__ */ jsxs("svg", { className: "crow-animate-spin crow-h-4 crow-w-4 crow-shrink-0 crow-text-[var(--crow-primary,#7c3aed)]", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
5383
+ /* @__PURE__ */ jsx("circle", { className: "crow-opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5384
+ /* @__PURE__ */ jsx("path", { className: "crow-opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
5385
+ ] }),
5386
+ /* @__PURE__ */ jsx("span", { className: "crow-font-medium crow-text-[var(--crow-text,#111827)]", children: toolStatus })
5128
5387
  ] }),
5129
- /* @__PURE__ */ jsx("span", { className: "crow-font-medium crow-text-[var(--crow-text,#111827)]", children: toolStatus })
5130
- ] }),
5131
- (chat.suggestedActions.length > 0 || !chat.isLoading && defaultSuggestedActionsRef.current.length > 0) && /* @__PURE__ */ jsx(
5132
- SuggestedActions,
5133
- {
5134
- actions: chat.suggestedActions.length > 0 ? chat.suggestedActions : defaultSuggestedActionsRef.current,
5135
- onActionClick: (action) => handleSend(action.message)
5136
- }
5137
- ),
5138
- /* @__PURE__ */ jsx(PoweredByBadge, { apiUrl }),
5139
- /* @__PURE__ */ jsx(
5140
- PromptInputBox,
5141
- {
5142
- onSend: handleSend,
5143
- onStop: handleStop,
5144
- placeholder: "Type your message...",
5145
- isLoading: chat.isLoading,
5146
- showStopButton: isBrowserUseActive || !!askUserResolver || !!pendingConfirmation,
5147
- highlighted: !!askUserResolver,
5148
- className: "crow-backdrop-blur-md",
5149
- backendUrl: apiUrl,
5150
- selectedModel: chat.selectedModel || selectedModelFromAPI,
5151
- onModelChange: chat.setSelectedModel,
5152
- availableModels: modelSelectionEnabled ? availableModelsFromAPI : []
5153
- }
5154
- )
5388
+ (chat.suggestedActions.length > 0 || !isOnboarding && !chat.isLoading && defaultSuggestedActionsRef.current.length > 0) && /* @__PURE__ */ jsx(
5389
+ SuggestedActions,
5390
+ {
5391
+ actions: chat.suggestedActions.length > 0 ? chat.suggestedActions : defaultSuggestedActionsRef.current,
5392
+ onActionClick: (action) => handleSend(action.message)
5393
+ }
5394
+ ),
5395
+ /* @__PURE__ */ jsx(PoweredByBadge, { apiUrl }),
5396
+ /* @__PURE__ */ jsx(
5397
+ PromptInputBox,
5398
+ {
5399
+ onSend: handleSend,
5400
+ onStop: handleStop,
5401
+ placeholder: "Type your message...",
5402
+ isLoading: chat.isLoading,
5403
+ showStopButton: isBrowserUseActive || !!askUserResolver || !!pendingConfirmation,
5404
+ highlighted: !!askUserResolver,
5405
+ className: "crow-backdrop-blur-md",
5406
+ backendUrl: apiUrl,
5407
+ selectedModel: chat.selectedModel || selectedModelFromAPI,
5408
+ onModelChange: chat.setSelectedModel,
5409
+ availableModels: modelSelectionEnabled ? availableModelsFromAPI : []
5410
+ }
5411
+ )
5412
+ ] })
5155
5413
  ] })
5156
5414
  ] });
5157
5415
  const combinedStyles = useMemo(
@@ -5165,7 +5423,7 @@ ${customCss}` : WIDGET_CSS,
5165
5423
  WidgetStyleProvider,
5166
5424
  {
5167
5425
  styles,
5168
- agentName,
5426
+ agentName: isOnboarding ? onboardingAgentName || agentName : agentName,
5169
5427
  isLoading: isLoadingStyles,
5170
5428
  variant,
5171
5429
  showThinking,
@@ -5462,6 +5720,78 @@ function CopilotContainer({
5462
5720
  )
5463
5721
  ] });
5464
5722
  }
5723
+ function OnboardingIntroInline2({
5724
+ lines,
5725
+ primaryColor,
5726
+ textColor,
5727
+ textMutedColor,
5728
+ onComplete
5729
+ }) {
5730
+ const [lineIndex, setLineIndex] = useState(0);
5731
+ const [charIndex, setCharIndex] = useState(0);
5732
+ const [done, setDone] = useState(false);
5733
+ useEffect(() => {
5734
+ if (lineIndex >= lines.length) {
5735
+ setDone(true);
5736
+ return;
5737
+ }
5738
+ const currentLine = lines[lineIndex];
5739
+ if (charIndex < currentLine.length) {
5740
+ const t = setTimeout(() => setCharIndex((c) => c + 1), 35);
5741
+ return () => clearTimeout(t);
5742
+ } else {
5743
+ const t = setTimeout(() => {
5744
+ setLineIndex((l) => l + 1);
5745
+ setCharIndex(0);
5746
+ }, 500);
5747
+ return () => clearTimeout(t);
5748
+ }
5749
+ }, [lineIndex, charIndex, lines]);
5750
+ const displayedLines = lines.slice(0, lineIndex + 1).map(
5751
+ (line, i) => i < lineIndex ? line : line.slice(0, charIndex)
5752
+ );
5753
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5754
+ /* @__PURE__ */ jsx("div", { style: { minHeight: "4rem", marginBottom: "1.5rem" }, children: displayedLines.map((text, i) => /* @__PURE__ */ jsxs("p", { style: {
5755
+ fontSize: i === 0 ? 18 : 14,
5756
+ fontWeight: i === 0 ? 600 : 400,
5757
+ color: i === 0 ? textColor : textMutedColor,
5758
+ lineHeight: 1.4,
5759
+ margin: "0 0 6px 0"
5760
+ }, children: [
5761
+ text,
5762
+ i === lineIndex && !done && /* @__PURE__ */ jsx("span", { style: {
5763
+ display: "inline-block",
5764
+ width: 2,
5765
+ height: i === 0 ? 18 : 14,
5766
+ backgroundColor: textColor,
5767
+ marginLeft: 2,
5768
+ verticalAlign: "middle",
5769
+ animation: "crow-blink 1s step-end infinite"
5770
+ } })
5771
+ ] }, i)) }),
5772
+ /* @__PURE__ */ jsx(
5773
+ "button",
5774
+ {
5775
+ onClick: onComplete,
5776
+ style: {
5777
+ padding: "8px 24px",
5778
+ borderRadius: 8,
5779
+ backgroundColor: primaryColor,
5780
+ color: "#fff",
5781
+ fontSize: 13,
5782
+ fontWeight: 500,
5783
+ border: "none",
5784
+ cursor: "pointer",
5785
+ opacity: done ? 1 : 0,
5786
+ pointerEvents: done ? "auto" : "none",
5787
+ transition: "opacity 0.5s ease"
5788
+ },
5789
+ children: "Get Started \u2192"
5790
+ }
5791
+ ),
5792
+ /* @__PURE__ */ jsx("style", { children: `@keyframes crow-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }` })
5793
+ ] });
5794
+ }
5465
5795
  function CrowCopilot({
5466
5796
  productId,
5467
5797
  apiUrl = "",
@@ -5485,7 +5815,10 @@ function CrowCopilot({
5485
5815
  getIdentityToken,
5486
5816
  context,
5487
5817
  language,
5488
- contextLabel: contextLabelProp
5818
+ contextLabel: contextLabelProp,
5819
+ forceOnboarding = false,
5820
+ fullscreenTopOffset: _fullscreenTopOffset = 0,
5821
+ mode: _mode
5489
5822
  }) {
5490
5823
  const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
5491
5824
  const effectiveOnToolResult = onToolResult || window.__crow_on_tool_result;
@@ -5503,7 +5836,11 @@ function CrowCopilot({
5503
5836
  toolConsentSettings,
5504
5837
  modelSelectionEnabled,
5505
5838
  availableModels: availableModelsFromAPI,
5506
- initialSuggestions
5839
+ initialSuggestions,
5840
+ onboardingEnabled,
5841
+ onboardingAgentName,
5842
+ onboardingWelcomeMessage,
5843
+ onboardingIntroSequence
5507
5844
  } = useCopilotStyles({
5508
5845
  productId,
5509
5846
  apiUrl,
@@ -5512,6 +5849,20 @@ function CrowCopilot({
5512
5849
  language
5513
5850
  });
5514
5851
  const agentName = agentNameProp ?? agentNameFromAPI ?? title;
5852
+ const [isOnboarding, setIsOnboarding] = useState(false);
5853
+ const [onboardingChecked, setOnboardingChecked] = useState(false);
5854
+ const [onboardingPhase, setOnboardingPhase] = useState("intro");
5855
+ useEffect(() => {
5856
+ if (forceOnboarding && !isLoadingStyles && onboardingEnabled && !onboardingChecked) {
5857
+ setIsOnboarding(true);
5858
+ setOnboardingChecked(true);
5859
+ }
5860
+ }, [forceOnboarding, isLoadingStyles, onboardingEnabled, onboardingChecked]);
5861
+ useEffect(() => {
5862
+ if (isOnboarding && !isLoadingStyles && onboardingIntroSequence !== void 0 && onboardingIntroSequence.length === 0) {
5863
+ setOnboardingPhase("chat");
5864
+ }
5865
+ }, [isOnboarding, isLoadingStyles, onboardingIntroSequence]);
5515
5866
  const [toolStatus, setToolStatus] = useState(
5516
5867
  () => window.__crow_tool_status ?? ""
5517
5868
  );
@@ -5692,10 +6043,10 @@ function CrowCopilot({
5692
6043
  };
5693
6044
  }, []);
5694
6045
  useEffect(() => {
5695
- if (initialSuggestions.length > 0 && chat.suggestedActions.length === 0) {
6046
+ if (!isOnboarding && initialSuggestions.length > 0 && chat.suggestedActions.length === 0) {
5696
6047
  chat.setSuggestedActions(initialSuggestions);
5697
6048
  }
5698
- }, [initialSuggestions]);
6049
+ }, [initialSuggestions, isOnboarding]);
5699
6050
  const messagesContainerRef = useRef(null);
5700
6051
  const tabsScrollRef = useRef(null);
5701
6052
  const executeClientToolRef = useRef(null);
@@ -5725,11 +6076,17 @@ function CrowCopilot({
5725
6076
  pendingRestoreConvId.current = "";
5726
6077
  }
5727
6078
  }
6079
+ const effectiveWelcomeMessage = isOnboarding ? onboardingWelcomeMessage || `Hi! I'm ${onboardingAgentName || agentName}. Let me help you get started.` : welcomeMessage;
5728
6080
  const chat = useChat({
5729
6081
  productId,
5730
6082
  apiUrl,
5731
6083
  persistAnonymousConversations,
5732
- welcomeMessage,
6084
+ welcomeMessage: effectiveWelcomeMessage,
6085
+ agentMode: isOnboarding ? "onboarding" : void 0,
6086
+ onOnboardingComplete: (summary) => {
6087
+ console.log("[Crow] Onboarding complete:", summary);
6088
+ setIsOnboarding(false);
6089
+ },
5733
6090
  selectedModel,
5734
6091
  subdomain,
5735
6092
  toolConsentSettings,
@@ -5873,6 +6230,33 @@ function CrowCopilot({
5873
6230
  const { executeClientTool } = useCrowAPI({
5874
6231
  onIdentified: async () => {
5875
6232
  setIsVerifiedUser(true);
6233
+ if (forceOnboarding) {
6234
+ setIsOnboarding(true);
6235
+ setOnboardingChecked(true);
6236
+ } else if (onboardingEnabled && !onboardingChecked) {
6237
+ try {
6238
+ const identityToken = window.__crow_identity_token;
6239
+ if (identityToken) {
6240
+ const res = await fetch(`${apiUrl}/api/chat/resolve-agent`, {
6241
+ method: "POST",
6242
+ headers: { "Content-Type": "application/json" },
6243
+ body: JSON.stringify({
6244
+ product_id: productId,
6245
+ identity_token: identityToken
6246
+ })
6247
+ });
6248
+ if (res.ok) {
6249
+ const data = await res.json();
6250
+ if (data.agent === "onboarding") {
6251
+ setIsOnboarding(true);
6252
+ }
6253
+ }
6254
+ }
6255
+ } catch (e) {
6256
+ console.error("[Crow] resolve-agent failed:", e);
6257
+ }
6258
+ setOnboardingChecked(true);
6259
+ }
5876
6260
  await conversations.loadConversations();
5877
6261
  const savedId = pendingRestoreConvId.current;
5878
6262
  if (savedId && !hasRestoredActiveConvRef.current) {
@@ -5895,6 +6279,16 @@ function CrowCopilot({
5895
6279
  });
5896
6280
  executeClientToolRef.current = executeClientTool;
5897
6281
  submitToolResultRef.current = chat.submitToolResult;
6282
+ const prevOnboardingRef = useRef(isOnboarding);
6283
+ useEffect(() => {
6284
+ if (isOnboarding && !prevOnboardingRef.current) {
6285
+ chat.setSuggestedActions([]);
6286
+ }
6287
+ if (prevOnboardingRef.current && !isOnboarding) {
6288
+ chat.resetMessages();
6289
+ }
6290
+ prevOnboardingRef.current = isOnboarding;
6291
+ }, [isOnboarding]);
5898
6292
  const handleBrowserConfirmation = useCallback(
5899
6293
  (instruction) => {
5900
6294
  return new Promise((resolve) => {
@@ -6235,312 +6629,347 @@ function CrowCopilot({
6235
6629
  "--crow-bg-active": styles.colors.text + "18"
6236
6630
  },
6237
6631
  children: [
6238
- /* @__PURE__ */ jsxs(
6239
- "div",
6240
- {
6241
- className: "crow-flex crow-items-stretch crow-border-b crow-min-h-[40px]",
6242
- style: { borderColor: styles.colors.border },
6243
- children: [
6244
- /* @__PURE__ */ jsx(
6245
- "div",
6246
- {
6247
- ref: tabsScrollRef,
6248
- className: "crow-flex crow-items-stretch crow-flex-1 crow-min-w-0 crow-overflow-x-auto",
6249
- style: {
6250
- scrollbarWidth: "none",
6251
- msOverflowStyle: "none"
6252
- },
6253
- onScroll: handleTabsScroll,
6254
- children: tabs.map((tab, idx) => {
6255
- const isActive = activeTabId === tab.id;
6256
- const isHovered = hoveredTabId === tab.id;
6257
- const isCloseable = tab.type !== "new" && (tab.type !== "local" || localTabs.length > 1);
6258
- return /* @__PURE__ */ jsxs(
6259
- "div",
6260
- {
6261
- className: "crow-relative crow-flex-shrink-0 crow-flex crow-items-center crow-text-[13px] crow-leading-tight crow-py-2.5 crow-transition-colors crow-select-none crow-cursor-pointer",
6262
- style: {
6263
- color: isActive ? styles.colors.text : styles.colors.text + "80",
6264
- fontWeight: isActive ? 500 : void 0,
6265
- maxWidth: "180px",
6266
- borderRight: idx < tabs.length - 1 ? `1px solid ${styles.colors.border}` : "none",
6267
- paddingLeft: "16px",
6268
- paddingRight: isCloseable ? "8px" : "16px"
6269
- },
6270
- title: tab.name,
6271
- onMouseEnter: () => setHoveredTabId(tab.id),
6272
- onMouseLeave: () => setHoveredTabId(null),
6273
- onClick: () => {
6274
- if (tab.type === "new") {
6275
- handleNewChat();
6276
- return;
6277
- }
6278
- if (tab.type === "server") {
6279
- handleSelectConversation(tab.id);
6280
- return;
6281
- }
6282
- handleSelectLocalTab(tab.id);
6283
- },
6284
- children: [
6285
- /* @__PURE__ */ jsx(
6286
- "span",
6287
- {
6288
- className: "crow-block crow-truncate",
6289
- style: { maxWidth: isCloseable ? "112px" : "128px" },
6290
- children: tab.name
6291
- }
6292
- ),
6293
- isCloseable && /* @__PURE__ */ jsx(
6294
- "span",
6295
- {
6296
- className: "crow-rounded crow-p-0.5 crow-flex-shrink-0 crow-inline-flex crow-items-center crow-justify-center crow-transition-opacity",
6297
- style: {
6298
- marginLeft: "6px",
6299
- opacity: isHovered ? 1 : 0,
6300
- pointerEvents: isHovered ? "auto" : "none"
6301
- },
6302
- onClick: (e) => {
6303
- e.stopPropagation();
6304
- handleCloseTab(tab.id, tab.type);
6305
- },
6306
- role: "button",
6307
- "aria-label": `Close ${tab.name}`,
6308
- children: /* @__PURE__ */ jsx(TabCloseIcon, { className: "crow-w-3 crow-h-3", style: { color: styles.colors.text + "80" } })
6309
- }
6310
- ),
6311
- isActive && /* @__PURE__ */ jsx(
6312
- "span",
6313
- {
6314
- className: "crow-absolute crow-bottom-0 crow-left-0 crow-right-0",
6315
- style: {
6316
- height: "2px",
6317
- background: styles.colors.primary || "#2563eb"
6318
- }
6319
- }
6320
- )
6321
- ]
6322
- },
6323
- `${tab.id}-${idx}`
6324
- );
6325
- })
6326
- }
6327
- ),
6328
- /* @__PURE__ */ jsxs(
6329
- "div",
6330
- {
6331
- className: "crow-flex crow-items-center crow-flex-shrink-0 crow-border-l",
6332
- style: { borderColor: styles.colors.border },
6333
- children: [
6334
- /* @__PURE__ */ jsx(
6335
- "button",
6336
- {
6337
- onClick: handleNewChat,
6338
- className: "crow-p-2 crow-transition-colors crow-rounded",
6339
- style: { color: styles.colors.text + "80" },
6340
- onMouseEnter: (e) => {
6341
- e.currentTarget.style.background = styles.colors.text + "10";
6342
- },
6343
- onMouseLeave: (e) => {
6344
- e.currentTarget.style.background = "transparent";
6345
- },
6346
- "aria-label": "New Chat",
6347
- title: "New Chat",
6348
- children: /* @__PURE__ */ jsx(PlusIcon, { className: "crow-w-4 crow-h-4" })
6349
- }
6350
- ),
6351
- /* @__PURE__ */ jsx(
6352
- "button",
6353
- {
6354
- onClick: handleToggleHistory,
6355
- disabled: !isVerifiedUser,
6356
- "aria-disabled": !isVerifiedUser,
6357
- className: `crow-p-2 crow-transition-colors crow-rounded ${!isVerifiedUser ? "crow-opacity-40 crow-cursor-not-allowed" : ""}`,
6358
- style: {
6359
- color: styles.colors.text + "80",
6360
- background: showConversationList ? styles.colors.text + "10" : "transparent"
6361
- },
6362
- onMouseEnter: (e) => {
6363
- if (isVerifiedUser) e.currentTarget.style.background = styles.colors.text + "10";
6364
- },
6365
- onMouseLeave: (e) => {
6366
- if (!showConversationList) e.currentTarget.style.background = "transparent";
6367
- },
6368
- "aria-label": "Conversation History",
6369
- title: isVerifiedUser ? "Conversation History" : "Sign in to view history",
6370
- children: /* @__PURE__ */ jsx(HistoryIcon, { className: "crow-w-4 crow-h-4" })
6371
- }
6372
- ),
6373
- canScrollRight && /* @__PURE__ */ jsx(
6374
- "button",
6375
- {
6376
- onClick: handleScrollRight,
6377
- className: "crow-p-2 crow-transition-colors crow-rounded",
6378
- style: { color: styles.colors.text + "80" },
6379
- onMouseEnter: (e) => {
6380
- e.currentTarget.style.background = styles.colors.text + "10";
6381
- },
6382
- onMouseLeave: (e) => {
6383
- e.currentTarget.style.background = "transparent";
6384
- },
6385
- "aria-label": "Scroll tabs",
6386
- title: "Scroll tabs",
6387
- children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "crow-w-4 crow-h-4" })
6388
- }
6389
- ),
6390
- (forceShowClose ?? showClose) && (overrideOnClose ?? onClose) && /* @__PURE__ */ jsx(
6391
- "button",
6392
- {
6393
- onClick: overrideOnClose ?? onClose,
6394
- className: "crow-p-2 crow-transition-colors crow-rounded",
6395
- style: { color: styles.colors.text + "80" },
6396
- onMouseEnter: (e) => {
6397
- e.currentTarget.style.background = styles.colors.text + "10";
6398
- },
6399
- onMouseLeave: (e) => {
6400
- e.currentTarget.style.background = "transparent";
6401
- },
6402
- "aria-label": "Close",
6403
- children: /* @__PURE__ */ jsx(CloseIcon, { className: "crow-w-4 crow-h-4" })
6404
- }
6405
- )
6406
- ]
6407
- }
6408
- )
6409
- ]
6410
- }
6411
- ),
6412
- contextLabel && /* @__PURE__ */ jsxs(
6413
- "div",
6414
- {
6415
- className: "crow-flex crow-items-center crow-gap-1.5 crow-px-3 crow-py-1.5 crow-border-b crow-text-xs",
6416
- style: {
6417
- color: styles.colors.text + "80",
6418
- borderColor: styles.colors.border
6419
- },
6420
- children: [
6421
- /* @__PURE__ */ jsxs(
6422
- "svg",
6423
- {
6424
- xmlns: "http://www.w3.org/2000/svg",
6425
- width: "12",
6426
- height: "12",
6427
- viewBox: "0 0 24 24",
6428
- fill: "none",
6429
- stroke: "currentColor",
6430
- strokeWidth: "2",
6431
- strokeLinecap: "round",
6432
- strokeLinejoin: "round",
6433
- className: "crow-shrink-0",
6434
- children: [
6435
- /* @__PURE__ */ jsx("path", { d: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" }),
6436
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "10", r: "3" })
6437
- ]
6438
- }
6439
- ),
6440
- /* @__PURE__ */ jsx("span", { className: "crow-truncate", children: contextLabel })
6441
- ]
6442
- }
6443
- ),
6444
- /* @__PURE__ */ jsxs(AnimatePresence, { children: [
6445
- showConversationList && isVerifiedUser && /* @__PURE__ */ jsx(
6446
- ConversationList,
6632
+ isOnboarding && /* @__PURE__ */ jsxs(Fragment, { children: [
6633
+ /* @__PURE__ */ jsxs(
6634
+ "div",
6447
6635
  {
6448
- conversations: conversations.conversations,
6449
- currentConversationId: chat.conversationId,
6450
- onSelect: handleSelectConversation,
6451
- onClose: handleCloseConversationList
6636
+ className: "crow-flex crow-items-center crow-justify-between crow-border-b crow-px-4 crow-py-2.5",
6637
+ style: { borderColor: styles.colors.border },
6638
+ children: [
6639
+ /* @__PURE__ */ jsx("span", { className: "crow-text-[13px] crow-font-semibold", style: { color: styles.colors.text }, children: onboardingAgentName || agentName }),
6640
+ /* @__PURE__ */ jsx(
6641
+ "button",
6642
+ {
6643
+ onClick: () => {
6644
+ setIsOnboarding(false);
6645
+ },
6646
+ className: "crow-text-xs crow-border-none crow-bg-transparent crow-cursor-pointer crow-px-2 crow-py-1",
6647
+ style: { color: styles.colors.text + "60" },
6648
+ children: "Skip"
6649
+ }
6650
+ )
6651
+ ]
6452
6652
  }
6453
6653
  ),
6454
- showConversationList && !isVerifiedUser && /* @__PURE__ */ jsx(
6455
- "div",
6654
+ onboardingPhase === "intro" && /* @__PURE__ */ jsx("div", { className: "crow-flex crow-flex-col crow-items-center crow-justify-center crow-flex-1 crow-px-4 crow-py-6 crow-text-center", children: /* @__PURE__ */ jsx(
6655
+ OnboardingIntroInline2,
6456
6656
  {
6457
- className: "crow-mb-3 crow-rounded-xl crow-border crow-p-4",
6458
- style: { background: styles.colors.text + "08", borderColor: styles.colors.border },
6459
- children: /* @__PURE__ */ jsx("div", { className: "crow-text-sm", style: { color: styles.colors.text + "99" }, children: "Sign in to view conversation history." })
6657
+ lines: onboardingIntroSequence || [],
6658
+ primaryColor: styles.colors.primary,
6659
+ textColor: styles.colors.text,
6660
+ textMutedColor: styles.colors.text + "80",
6661
+ onComplete: () => setOnboardingPhase("chat")
6460
6662
  }
6461
- )
6663
+ ) })
6462
6664
  ] }),
6463
- /* @__PURE__ */ jsx(AnimatePresence, { children: activeWorkflow && /* @__PURE__ */ jsx(
6464
- WorkflowPanel,
6465
- {
6466
- workflow: activeWorkflow,
6467
- onExit: handleExitWorkflow
6468
- }
6469
- ) }),
6470
- /* @__PURE__ */ jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
6471
- /* @__PURE__ */ jsx(
6472
- MessageList,
6665
+ !(isOnboarding && onboardingPhase === "intro") && /* @__PURE__ */ jsxs(Fragment, { children: [
6666
+ !isOnboarding && /* @__PURE__ */ jsxs(
6667
+ "div",
6473
6668
  {
6474
- messages: chat.messages,
6475
- activeToolCalls: chat.activeToolCalls,
6476
- isLoadingHistory: conversations.isLoadingHistory,
6477
- isGenerating: chat.isLoading,
6478
- toolRenderers: effectiveToolRenderers,
6479
- onToolConsent: handleToolConsent
6669
+ className: "crow-flex crow-items-stretch crow-border-b crow-min-h-[40px]",
6670
+ style: { borderColor: styles.colors.border },
6671
+ children: [
6672
+ /* @__PURE__ */ jsx(
6673
+ "div",
6674
+ {
6675
+ ref: tabsScrollRef,
6676
+ className: "crow-flex crow-items-stretch crow-flex-1 crow-min-w-0 crow-overflow-x-auto",
6677
+ style: {
6678
+ scrollbarWidth: "none",
6679
+ msOverflowStyle: "none"
6680
+ },
6681
+ onScroll: handleTabsScroll,
6682
+ children: tabs.map((tab, idx) => {
6683
+ const isActive = activeTabId === tab.id;
6684
+ const isHovered = hoveredTabId === tab.id;
6685
+ const isCloseable = tab.type !== "new" && (tab.type !== "local" || localTabs.length > 1);
6686
+ return /* @__PURE__ */ jsxs(
6687
+ "div",
6688
+ {
6689
+ className: "crow-relative crow-flex-shrink-0 crow-flex crow-items-center crow-text-[13px] crow-leading-tight crow-py-2.5 crow-transition-colors crow-select-none crow-cursor-pointer",
6690
+ style: {
6691
+ color: isActive ? styles.colors.text : styles.colors.text + "80",
6692
+ fontWeight: isActive ? 500 : void 0,
6693
+ maxWidth: "180px",
6694
+ borderRight: idx < tabs.length - 1 ? `1px solid ${styles.colors.border}` : "none",
6695
+ paddingLeft: "16px",
6696
+ paddingRight: isCloseable ? "8px" : "16px"
6697
+ },
6698
+ title: tab.name,
6699
+ onMouseEnter: () => setHoveredTabId(tab.id),
6700
+ onMouseLeave: () => setHoveredTabId(null),
6701
+ onClick: () => {
6702
+ if (tab.type === "new") {
6703
+ handleNewChat();
6704
+ return;
6705
+ }
6706
+ if (tab.type === "server") {
6707
+ handleSelectConversation(tab.id);
6708
+ return;
6709
+ }
6710
+ handleSelectLocalTab(tab.id);
6711
+ },
6712
+ children: [
6713
+ /* @__PURE__ */ jsx(
6714
+ "span",
6715
+ {
6716
+ className: "crow-block crow-truncate",
6717
+ style: { maxWidth: isCloseable ? "112px" : "128px" },
6718
+ children: tab.name
6719
+ }
6720
+ ),
6721
+ isCloseable && /* @__PURE__ */ jsx(
6722
+ "span",
6723
+ {
6724
+ className: "crow-rounded crow-p-0.5 crow-flex-shrink-0 crow-inline-flex crow-items-center crow-justify-center crow-transition-opacity",
6725
+ style: {
6726
+ marginLeft: "6px",
6727
+ opacity: isHovered ? 1 : 0,
6728
+ pointerEvents: isHovered ? "auto" : "none"
6729
+ },
6730
+ onClick: (e) => {
6731
+ e.stopPropagation();
6732
+ handleCloseTab(tab.id, tab.type);
6733
+ },
6734
+ role: "button",
6735
+ "aria-label": `Close ${tab.name}`,
6736
+ children: /* @__PURE__ */ jsx(TabCloseIcon, { className: "crow-w-3 crow-h-3", style: { color: styles.colors.text + "80" } })
6737
+ }
6738
+ ),
6739
+ isActive && /* @__PURE__ */ jsx(
6740
+ "span",
6741
+ {
6742
+ className: "crow-absolute crow-bottom-0 crow-left-0 crow-right-0",
6743
+ style: {
6744
+ height: "2px",
6745
+ background: styles.colors.primary || "#2563eb"
6746
+ }
6747
+ }
6748
+ )
6749
+ ]
6750
+ },
6751
+ `${tab.id}-${idx}`
6752
+ );
6753
+ })
6754
+ }
6755
+ ),
6756
+ /* @__PURE__ */ jsxs(
6757
+ "div",
6758
+ {
6759
+ className: "crow-flex crow-items-center crow-flex-shrink-0 crow-border-l",
6760
+ style: { borderColor: styles.colors.border },
6761
+ children: [
6762
+ /* @__PURE__ */ jsx(
6763
+ "button",
6764
+ {
6765
+ onClick: handleNewChat,
6766
+ className: "crow-p-2 crow-transition-colors crow-rounded",
6767
+ style: { color: styles.colors.text + "80" },
6768
+ onMouseEnter: (e) => {
6769
+ e.currentTarget.style.background = styles.colors.text + "10";
6770
+ },
6771
+ onMouseLeave: (e) => {
6772
+ e.currentTarget.style.background = "transparent";
6773
+ },
6774
+ "aria-label": "New Chat",
6775
+ title: "New Chat",
6776
+ children: /* @__PURE__ */ jsx(PlusIcon, { className: "crow-w-4 crow-h-4" })
6777
+ }
6778
+ ),
6779
+ /* @__PURE__ */ jsx(
6780
+ "button",
6781
+ {
6782
+ onClick: handleToggleHistory,
6783
+ disabled: !isVerifiedUser,
6784
+ "aria-disabled": !isVerifiedUser,
6785
+ className: `crow-p-2 crow-transition-colors crow-rounded ${!isVerifiedUser ? "crow-opacity-40 crow-cursor-not-allowed" : ""}`,
6786
+ style: {
6787
+ color: styles.colors.text + "80",
6788
+ background: showConversationList ? styles.colors.text + "10" : "transparent"
6789
+ },
6790
+ onMouseEnter: (e) => {
6791
+ if (isVerifiedUser) e.currentTarget.style.background = styles.colors.text + "10";
6792
+ },
6793
+ onMouseLeave: (e) => {
6794
+ if (!showConversationList) e.currentTarget.style.background = "transparent";
6795
+ },
6796
+ "aria-label": "Conversation History",
6797
+ title: isVerifiedUser ? "Conversation History" : "Sign in to view history",
6798
+ children: /* @__PURE__ */ jsx(HistoryIcon, { className: "crow-w-4 crow-h-4" })
6799
+ }
6800
+ ),
6801
+ canScrollRight && /* @__PURE__ */ jsx(
6802
+ "button",
6803
+ {
6804
+ onClick: handleScrollRight,
6805
+ className: "crow-p-2 crow-transition-colors crow-rounded",
6806
+ style: { color: styles.colors.text + "80" },
6807
+ onMouseEnter: (e) => {
6808
+ e.currentTarget.style.background = styles.colors.text + "10";
6809
+ },
6810
+ onMouseLeave: (e) => {
6811
+ e.currentTarget.style.background = "transparent";
6812
+ },
6813
+ "aria-label": "Scroll tabs",
6814
+ title: "Scroll tabs",
6815
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "crow-w-4 crow-h-4" })
6816
+ }
6817
+ ),
6818
+ (forceShowClose ?? showClose) && (overrideOnClose ?? onClose) && /* @__PURE__ */ jsx(
6819
+ "button",
6820
+ {
6821
+ onClick: overrideOnClose ?? onClose,
6822
+ className: "crow-p-2 crow-transition-colors crow-rounded",
6823
+ style: { color: styles.colors.text + "80" },
6824
+ onMouseEnter: (e) => {
6825
+ e.currentTarget.style.background = styles.colors.text + "10";
6826
+ },
6827
+ onMouseLeave: (e) => {
6828
+ e.currentTarget.style.background = "transparent";
6829
+ },
6830
+ "aria-label": "Close",
6831
+ children: /* @__PURE__ */ jsx(CloseIcon, { className: "crow-w-4 crow-h-4" })
6832
+ }
6833
+ )
6834
+ ]
6835
+ }
6836
+ )
6837
+ ]
6480
6838
  }
6481
6839
  ),
6482
- pendingConfirmation && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
6483
- BrowserUseConfirmation,
6840
+ contextLabel && /* @__PURE__ */ jsxs(
6841
+ "div",
6484
6842
  {
6485
- instruction: pendingConfirmation.instruction,
6486
- onAllow: () => {
6487
- pendingConfirmation.resolve(true);
6488
- setPendingConfirmation(null);
6843
+ className: "crow-flex crow-items-center crow-gap-1.5 crow-px-3 crow-py-1.5 crow-border-b crow-text-xs",
6844
+ style: {
6845
+ color: styles.colors.text + "80",
6846
+ borderColor: styles.colors.border
6489
6847
  },
6490
- onDeny: () => {
6491
- pendingConfirmation.resolve(false);
6492
- setPendingConfirmation(null);
6848
+ children: [
6849
+ /* @__PURE__ */ jsxs(
6850
+ "svg",
6851
+ {
6852
+ xmlns: "http://www.w3.org/2000/svg",
6853
+ width: "12",
6854
+ height: "12",
6855
+ viewBox: "0 0 24 24",
6856
+ fill: "none",
6857
+ stroke: "currentColor",
6858
+ strokeWidth: "2",
6859
+ strokeLinecap: "round",
6860
+ strokeLinejoin: "round",
6861
+ className: "crow-shrink-0",
6862
+ children: [
6863
+ /* @__PURE__ */ jsx("path", { d: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" }),
6864
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "10", r: "3" })
6865
+ ]
6866
+ }
6867
+ ),
6868
+ /* @__PURE__ */ jsx("span", { className: "crow-truncate", children: contextLabel })
6869
+ ]
6870
+ }
6871
+ ),
6872
+ /* @__PURE__ */ jsxs(AnimatePresence, { children: [
6873
+ showConversationList && isVerifiedUser && /* @__PURE__ */ jsx(
6874
+ ConversationList,
6875
+ {
6876
+ conversations: conversations.conversations,
6877
+ currentConversationId: chat.conversationId,
6878
+ onSelect: handleSelectConversation,
6879
+ onClose: handleCloseConversationList
6493
6880
  }
6881
+ ),
6882
+ showConversationList && !isVerifiedUser && /* @__PURE__ */ jsx(
6883
+ "div",
6884
+ {
6885
+ className: "crow-mb-3 crow-rounded-xl crow-border crow-p-4",
6886
+ style: { background: styles.colors.text + "08", borderColor: styles.colors.border },
6887
+ children: /* @__PURE__ */ jsx("div", { className: "crow-text-sm", style: { color: styles.colors.text + "99" }, children: "Sign in to view conversation history." })
6888
+ }
6889
+ )
6890
+ ] }),
6891
+ /* @__PURE__ */ jsx(AnimatePresence, { children: activeWorkflow && /* @__PURE__ */ jsx(
6892
+ WorkflowPanel,
6893
+ {
6894
+ workflow: activeWorkflow,
6895
+ onExit: handleExitWorkflow
6494
6896
  }
6495
6897
  ) }),
6496
- askUserResolver && browserQuestion && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
6497
- BrowserUseQuestion,
6498
- {
6499
- question: browserQuestion,
6500
- onSubmit: (answer) => {
6501
- askUserResolver.resolve(answer);
6502
- setAskUserResolver(null);
6503
- setBrowserQuestion(null);
6898
+ /* @__PURE__ */ jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
6899
+ /* @__PURE__ */ jsx(
6900
+ MessageList,
6901
+ {
6902
+ messages: chat.messages,
6903
+ activeToolCalls: chat.activeToolCalls,
6904
+ isLoadingHistory: conversations.isLoadingHistory,
6905
+ isGenerating: chat.isLoading,
6906
+ toolRenderers: effectiveToolRenderers,
6907
+ onToolConsent: handleToolConsent
6504
6908
  }
6505
- }
6506
- ) })
6507
- ] }),
6508
- /* @__PURE__ */ jsxs(
6509
- "div",
6510
- {
6511
- className: "crow-p-3 crow-border-t",
6512
- style: { borderColor: styles.colors.border },
6513
- children: [
6514
- toolStatus && /* @__PURE__ */ jsxs("div", { className: "crow-mb-1 crow-flex crow-items-center crow-gap-2 crow-rounded-lg crow-border crow-px-3 crow-py-2 crow-text-sm", style: { borderColor: styles.colors.border, background: styles.colors.border + "30" }, children: [
6515
- /* @__PURE__ */ jsxs("svg", { className: "crow-animate-spin crow-h-4 crow-w-4 crow-shrink-0 crow-text-[var(--crow-primary,#7c3aed)]", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
6516
- /* @__PURE__ */ jsx("circle", { className: "crow-opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6517
- /* @__PURE__ */ jsx("path", { className: "crow-opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
6518
- ] }),
6519
- /* @__PURE__ */ jsx("span", { className: "crow-font-medium crow-text-[var(--crow-text,#111827)]", children: toolStatus })
6520
- ] }),
6521
- (chat.suggestedActions.length > 0 || !chat.isLoading && defaultSuggestedActionsRef.current.length > 0) && /* @__PURE__ */ jsx(
6522
- SuggestedActions,
6523
- {
6524
- actions: chat.suggestedActions.length > 0 ? chat.suggestedActions : defaultSuggestedActionsRef.current,
6525
- onActionClick: (action) => handleSend(action.message)
6909
+ ),
6910
+ pendingConfirmation && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
6911
+ BrowserUseConfirmation,
6912
+ {
6913
+ instruction: pendingConfirmation.instruction,
6914
+ onAllow: () => {
6915
+ pendingConfirmation.resolve(true);
6916
+ setPendingConfirmation(null);
6917
+ },
6918
+ onDeny: () => {
6919
+ pendingConfirmation.resolve(false);
6920
+ setPendingConfirmation(null);
6526
6921
  }
6527
- ),
6528
- styles.branding.showPoweredBy && /* @__PURE__ */ jsx(PoweredByBadge, { apiUrl }),
6529
- /* @__PURE__ */ jsx(
6530
- PromptInputBox,
6531
- {
6532
- onSend: handleSend,
6533
- onStop: handleStop,
6534
- placeholder: "Ask anything...",
6535
- isLoading: chat.isLoading,
6536
- selectedModel: chat.selectedModel || selectedModel,
6537
- onModelChange: chat.setSelectedModel,
6538
- availableModels: modelSelectionEnabled ? availableModelsFromAPI : []
6922
+ }
6923
+ ) }),
6924
+ askUserResolver && browserQuestion && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
6925
+ BrowserUseQuestion,
6926
+ {
6927
+ question: browserQuestion,
6928
+ onSubmit: (answer) => {
6929
+ askUserResolver.resolve(answer);
6930
+ setAskUserResolver(null);
6931
+ setBrowserQuestion(null);
6539
6932
  }
6540
- )
6541
- ]
6542
- }
6543
- )
6933
+ }
6934
+ ) })
6935
+ ] }),
6936
+ /* @__PURE__ */ jsxs(
6937
+ "div",
6938
+ {
6939
+ className: "crow-p-3 crow-border-t",
6940
+ style: { borderColor: styles.colors.border },
6941
+ children: [
6942
+ toolStatus && /* @__PURE__ */ jsxs("div", { className: "crow-mb-1 crow-flex crow-items-center crow-gap-2 crow-rounded-lg crow-border crow-px-3 crow-py-2 crow-text-sm", style: { borderColor: styles.colors.border, background: styles.colors.border + "30" }, children: [
6943
+ /* @__PURE__ */ jsxs("svg", { className: "crow-animate-spin crow-h-4 crow-w-4 crow-shrink-0 crow-text-[var(--crow-primary,#7c3aed)]", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
6944
+ /* @__PURE__ */ jsx("circle", { className: "crow-opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6945
+ /* @__PURE__ */ jsx("path", { className: "crow-opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
6946
+ ] }),
6947
+ /* @__PURE__ */ jsx("span", { className: "crow-font-medium crow-text-[var(--crow-text,#111827)]", children: toolStatus })
6948
+ ] }),
6949
+ (chat.suggestedActions.length > 0 || !isOnboarding && !chat.isLoading && defaultSuggestedActionsRef.current.length > 0) && /* @__PURE__ */ jsx(
6950
+ SuggestedActions,
6951
+ {
6952
+ actions: chat.suggestedActions.length > 0 ? chat.suggestedActions : defaultSuggestedActionsRef.current,
6953
+ onActionClick: (action) => handleSend(action.message)
6954
+ }
6955
+ ),
6956
+ styles.branding.showPoweredBy && /* @__PURE__ */ jsx(PoweredByBadge, { apiUrl }),
6957
+ /* @__PURE__ */ jsx(
6958
+ PromptInputBox,
6959
+ {
6960
+ onSend: handleSend,
6961
+ onStop: handleStop,
6962
+ placeholder: "Ask anything...",
6963
+ isLoading: chat.isLoading,
6964
+ selectedModel: chat.selectedModel || selectedModel,
6965
+ onModelChange: chat.setSelectedModel,
6966
+ availableModels: modelSelectionEnabled ? availableModelsFromAPI : []
6967
+ }
6968
+ )
6969
+ ]
6970
+ }
6971
+ )
6972
+ ] })
6544
6973
  ]
6545
6974
  }
6546
6975
  )
@@ -6562,7 +6991,7 @@ function CrowCopilot({
6562
6991
  const edgeSide = isRight ? "left" : "right";
6563
6992
  const toggleIconColor = styles.colors.text + "80";
6564
6993
  const toggleIcon = isCollapsed ? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: toggleIconColor, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }) }) : /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: toggleIconColor, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: isRight ? /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) : /* @__PURE__ */ jsx("path", { d: "m15 18-6-6 6-6" }) });
6565
- return /* @__PURE__ */ jsxs("div", { style: { position: "relative", flexShrink: 0, height: "100%" }, children: [
6994
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { style: { position: "relative", flexShrink: 0, height: "100%" }, children: [
6566
6995
  /* @__PURE__ */ jsx(
6567
6996
  "button",
6568
6997
  {
@@ -6606,7 +7035,7 @@ function CrowCopilot({
6606
7035
  children: /* @__PURE__ */ jsx(ShadowContainer, { styles: WIDGET_CSS, children: renderCopilotContent(void 0, false, "100%") })
6607
7036
  }
6608
7037
  )
6609
- ] });
7038
+ ] }) });
6610
7039
  }
6611
7040
  function PlusIcon({ className }) {
6612
7041
  return /* @__PURE__ */ jsxs(
@@ -6712,6 +7141,320 @@ function CloseIcon({ className }) {
6712
7141
  }
6713
7142
  );
6714
7143
  }
7144
+ function IntroSequence({ lines, onComplete, onSkip, primaryColor }) {
7145
+ const [lineIndex, setLineIndex] = useState(0);
7146
+ const [charIndex, setCharIndex] = useState(0);
7147
+ const [done, setDone] = useState(false);
7148
+ useEffect(() => {
7149
+ if (lineIndex >= lines.length) {
7150
+ setDone(true);
7151
+ return;
7152
+ }
7153
+ const currentLine = lines[lineIndex];
7154
+ if (charIndex < currentLine.length) {
7155
+ const t = setTimeout(() => setCharIndex((c) => c + 1), 35);
7156
+ return () => clearTimeout(t);
7157
+ } else {
7158
+ const t = setTimeout(() => {
7159
+ setLineIndex((l) => l + 1);
7160
+ setCharIndex(0);
7161
+ }, 500);
7162
+ return () => clearTimeout(t);
7163
+ }
7164
+ }, [lineIndex, charIndex, lines]);
7165
+ const displayedLines = lines.slice(0, lineIndex + 1).map((line, i) => {
7166
+ if (i < lineIndex) return line;
7167
+ return line.slice(0, charIndex);
7168
+ });
7169
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100%", padding: "2rem" }, children: [
7170
+ /* @__PURE__ */ jsx(
7171
+ "button",
7172
+ {
7173
+ onClick: onSkip,
7174
+ style: {
7175
+ position: "absolute",
7176
+ top: 20,
7177
+ right: 24,
7178
+ fontSize: 14,
7179
+ color: "#9ca3af",
7180
+ background: "none",
7181
+ border: "none",
7182
+ cursor: "pointer",
7183
+ padding: "4px 8px"
7184
+ },
7185
+ children: "Skip"
7186
+ }
7187
+ ),
7188
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", minHeight: "5rem", marginBottom: "2.5rem" }, children: displayedLines.map((text, i) => /* @__PURE__ */ jsxs(
7189
+ "p",
7190
+ {
7191
+ style: {
7192
+ fontSize: i === 0 ? 30 : 18,
7193
+ fontWeight: i === 0 ? 600 : 400,
7194
+ color: i === 0 ? "#111827" : "#6b7280",
7195
+ lineHeight: 1.4,
7196
+ margin: "0 0 8px 0"
7197
+ },
7198
+ children: [
7199
+ text,
7200
+ i === lineIndex && !done && /* @__PURE__ */ jsx(
7201
+ "span",
7202
+ {
7203
+ style: {
7204
+ display: "inline-block",
7205
+ width: 2,
7206
+ height: i === 0 ? 28 : 18,
7207
+ backgroundColor: "#111827",
7208
+ marginLeft: 2,
7209
+ verticalAlign: "middle",
7210
+ animation: "crow-blink 1s step-end infinite"
7211
+ }
7212
+ }
7213
+ )
7214
+ ]
7215
+ },
7216
+ i
7217
+ )) }),
7218
+ /* @__PURE__ */ jsx(
7219
+ "button",
7220
+ {
7221
+ onClick: onComplete,
7222
+ style: {
7223
+ padding: "10px 32px",
7224
+ borderRadius: 12,
7225
+ backgroundColor: primaryColor,
7226
+ color: "#fff",
7227
+ fontSize: 15,
7228
+ fontWeight: 500,
7229
+ border: "none",
7230
+ cursor: "pointer",
7231
+ opacity: done ? 1 : 0,
7232
+ pointerEvents: done ? "auto" : "none",
7233
+ transition: "opacity 0.5s ease"
7234
+ },
7235
+ children: "Get Started \u2192"
7236
+ }
7237
+ ),
7238
+ /* @__PURE__ */ jsx("style", { children: `
7239
+ @keyframes crow-blink {
7240
+ 0%, 100% { opacity: 1; }
7241
+ 50% { opacity: 0; }
7242
+ }
7243
+ ` })
7244
+ ] });
7245
+ }
7246
+ function CrowOnboarding({
7247
+ productId,
7248
+ apiUrl,
7249
+ subdomain,
7250
+ agentName,
7251
+ welcomeMessage,
7252
+ introSequence,
7253
+ topOffset = 0,
7254
+ onComplete,
7255
+ language,
7256
+ styles: preResolvedStyles,
7257
+ getIdentityToken
7258
+ }) {
7259
+ const [phase, setPhase] = useState(
7260
+ introSequence && introSequence.length > 0 ? "intro" : "chat"
7261
+ );
7262
+ const [isDismissing, setIsDismissing] = useState(false);
7263
+ const bottomRef = useRef(null);
7264
+ const styles = useMemo(
7265
+ () => preResolvedStyles || mergeWidgetStyles(void 0, void 0),
7266
+ [preResolvedStyles]
7267
+ );
7268
+ const cssVars = useMemo(
7269
+ () => stylesToCssVars(styles),
7270
+ [styles]
7271
+ );
7272
+ const dismiss = useCallback(() => {
7273
+ setIsDismissing(true);
7274
+ setTimeout(() => onComplete(), 400);
7275
+ }, [onComplete]);
7276
+ const handleOnboardingComplete = useCallback(
7277
+ (summary) => {
7278
+ console.log("[Crow] Onboarding complete:", summary);
7279
+ dismiss();
7280
+ },
7281
+ [dismiss]
7282
+ );
7283
+ const chat = useChat({
7284
+ productId,
7285
+ apiUrl,
7286
+ subdomain,
7287
+ welcomeMessage: welcomeMessage || `Hi! I'm ${agentName}. Let me help you get started.`,
7288
+ agentMode: "onboarding",
7289
+ onOnboardingComplete: handleOnboardingComplete,
7290
+ language
7291
+ });
7292
+ useEffect(() => {
7293
+ bottomRef.current?.scrollIntoView({ behavior: "smooth" });
7294
+ }, [chat.messages, chat.isLoading]);
7295
+ const handleSend = useCallback(
7296
+ (content) => {
7297
+ chat.sendMessage(content);
7298
+ },
7299
+ [chat]
7300
+ );
7301
+ const handleStop = useCallback(() => {
7302
+ chat.stopGeneration();
7303
+ }, [chat]);
7304
+ const handleSuggestedActionClick = useCallback(
7305
+ (action) => {
7306
+ chat.sendMessage(action.message);
7307
+ },
7308
+ [chat]
7309
+ );
7310
+ useEffect(() => {
7311
+ const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
7312
+ if (!effectiveGetIdentityToken) return;
7313
+ let cancelled = false;
7314
+ const identify = async () => {
7315
+ try {
7316
+ const token = await effectiveGetIdentityToken();
7317
+ if (!cancelled && token) {
7318
+ window.__crow_identity_token = token;
7319
+ }
7320
+ } catch (e) {
7321
+ console.error("[Crow] Onboarding getIdentityToken failed:", e);
7322
+ }
7323
+ };
7324
+ identify();
7325
+ return () => {
7326
+ cancelled = true;
7327
+ };
7328
+ }, [getIdentityToken]);
7329
+ const renderChat = () => /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", background: "#ffffff" }, children: [
7330
+ /* @__PURE__ */ jsxs("div", { style: {
7331
+ display: "flex",
7332
+ alignItems: "center",
7333
+ justifyContent: "space-between",
7334
+ padding: "12px 24px",
7335
+ borderBottom: "1px solid #f3f4f6",
7336
+ flexShrink: 0
7337
+ }, children: [
7338
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
7339
+ /* @__PURE__ */ jsx("div", { style: {
7340
+ width: 28,
7341
+ height: 28,
7342
+ borderRadius: "50%",
7343
+ backgroundColor: styles.colors.primary,
7344
+ display: "flex",
7345
+ alignItems: "center",
7346
+ justifyContent: "center",
7347
+ color: "#fff",
7348
+ fontSize: 13,
7349
+ fontWeight: 600,
7350
+ flexShrink: 0
7351
+ }, children: agentName.charAt(0).toUpperCase() }),
7352
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 14, fontWeight: 600, color: "#111827" }, children: agentName })
7353
+ ] }),
7354
+ /* @__PURE__ */ jsx(
7355
+ "button",
7356
+ {
7357
+ onClick: dismiss,
7358
+ style: {
7359
+ fontSize: 13,
7360
+ color: "#9ca3af",
7361
+ background: "none",
7362
+ border: "none",
7363
+ cursor: "pointer",
7364
+ padding: "4px 8px"
7365
+ },
7366
+ children: "Skip"
7367
+ }
7368
+ )
7369
+ ] }),
7370
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, overflowY: "auto", minHeight: 0 }, children: /* @__PURE__ */ jsxs("div", { className: "crow-widget-root", style: { ...cssVars, maxWidth: 560, margin: "0 auto", padding: "24px 16px" }, children: [
7371
+ /* @__PURE__ */ jsx(
7372
+ WidgetStyleProvider,
7373
+ {
7374
+ styles,
7375
+ agentName,
7376
+ isLoading: false,
7377
+ variant: "embedded",
7378
+ children: /* @__PURE__ */ jsx(
7379
+ MessageList,
7380
+ {
7381
+ messages: chat.messages,
7382
+ activeToolCalls: chat.activeToolCalls,
7383
+ isLoadingHistory: false,
7384
+ isGenerating: chat.isLoading
7385
+ }
7386
+ )
7387
+ }
7388
+ ),
7389
+ /* @__PURE__ */ jsx("div", { ref: bottomRef })
7390
+ ] }) }),
7391
+ chat.suggestedActions.length > 0 && !chat.isLoading && /* @__PURE__ */ jsx("div", { className: "crow-widget-root", style: { ...cssVars, maxWidth: 560, margin: "0 auto", width: "100%", padding: "0 16px 8px" }, children: /* @__PURE__ */ jsx(
7392
+ WidgetStyleProvider,
7393
+ {
7394
+ styles,
7395
+ agentName,
7396
+ isLoading: false,
7397
+ variant: "embedded",
7398
+ children: /* @__PURE__ */ jsx(
7399
+ SuggestedActions,
7400
+ {
7401
+ actions: chat.suggestedActions,
7402
+ onActionClick: handleSuggestedActionClick
7403
+ }
7404
+ )
7405
+ }
7406
+ ) }),
7407
+ /* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid #f3f4f6", flexShrink: 0 }, children: [
7408
+ /* @__PURE__ */ jsx("div", { className: "crow-widget-root", style: { ...cssVars, maxWidth: 560, margin: "0 auto", padding: "12px 16px" }, children: /* @__PURE__ */ jsx(
7409
+ WidgetStyleProvider,
7410
+ {
7411
+ styles,
7412
+ agentName,
7413
+ isLoading: false,
7414
+ variant: "embedded",
7415
+ children: /* @__PURE__ */ jsx(
7416
+ PromptInputBox,
7417
+ {
7418
+ onSend: handleSend,
7419
+ onStop: handleStop,
7420
+ placeholder: "Type your message...",
7421
+ isLoading: chat.isLoading
7422
+ }
7423
+ )
7424
+ }
7425
+ ) }),
7426
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", padding: "0 0 10px" }, children: /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: "#d1d5db" }, children: "Powered by Crow" }) })
7427
+ ] })
7428
+ ] });
7429
+ return /* @__PURE__ */ jsx(ShadowContainer, { styles: WIDGET_CSS, hostId: "crow-onboarding-host", children: /* @__PURE__ */ jsx(
7430
+ motion.div,
7431
+ {
7432
+ style: {
7433
+ position: "fixed",
7434
+ top: topOffset,
7435
+ left: 0,
7436
+ right: 0,
7437
+ bottom: 0,
7438
+ zIndex: 999999,
7439
+ background: "#ffffff",
7440
+ fontFamily: styles.typography.fontFamily || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
7441
+ fontSize: 14
7442
+ },
7443
+ initial: { opacity: 0 },
7444
+ animate: { opacity: isDismissing ? 0 : 1 },
7445
+ transition: { duration: 0.35 },
7446
+ children: phase === "intro" ? /* @__PURE__ */ jsx(
7447
+ IntroSequence,
7448
+ {
7449
+ lines: introSequence || [],
7450
+ onComplete: () => setPhase("chat"),
7451
+ onSkip: dismiss,
7452
+ primaryColor: styles.colors.primary
7453
+ }
7454
+ ) : renderChat()
7455
+ }
7456
+ ) });
7457
+ }
6715
7458
  var CrowContext = createContext(null);
6716
7459
  function CrowProvider({
6717
7460
  children,
@@ -6734,6 +7477,6 @@ function CrowProvider({
6734
7477
  return /* @__PURE__ */ jsx(CrowContext.Provider, { value, children });
6735
7478
  }
6736
7479
 
6737
- export { AVAILABLE_MODELS, CSS_VAR_NAMES, ChatBubble, ConversationList, CopilotContainer, CopilotStyleProvider, CopilotToggleButton, CrowCopilot, CrowProvider, CrowWidget, DEFAULT_COPILOT_STYLES, DEFAULT_MODEL, DEFAULT_WELCOME_MESSAGE, DEFAULT_WIDGET_STYLES, LoadingHistory, MESSAGES_CONTAINER_ID, MessageBubble, MessageList, MessagesContainer, ModelSelector, PoweredByBadge, PromptInputBox, ReasoningTrace, ShadowContainer, StreamingText, ThinkingIndicator, WIDGET_CSS, WidgetHeader, WidgetShell, WidgetStyleProvider, WorkflowPanel, clearStyleCache, getCssVar, injectStyles, mergeCopilotStyles, mergeWidgetStyles, stylesToCSSVariables, stylesToCssVars, useChat, useConversations, useCopilotStyleContext, useCopilotStyles, useCopilotStyles2 as useCopilotStylesContext, useCrowAPI, usePreviewCopilotStyles, usePreviewWidgetStyles, useVoiceInput, useWidgetStyleContext, useWidgetStyles, useWidgetStyles2 as useWidgetStylesContext, useWorkflow };
7480
+ export { AVAILABLE_MODELS, CSS_VAR_NAMES, ChatBubble, ConversationList, CopilotContainer, CopilotStyleProvider, CopilotToggleButton, CrowCopilot, CrowOnboarding, CrowProvider, CrowWidget, DEFAULT_COPILOT_STYLES, DEFAULT_MODEL, DEFAULT_WELCOME_MESSAGE, DEFAULT_WIDGET_STYLES, LoadingHistory, MESSAGES_CONTAINER_ID, MessageBubble, MessageList, MessagesContainer, ModelSelector, PoweredByBadge, PromptInputBox, ReasoningTrace, ShadowContainer, StreamingText, ThinkingIndicator, WIDGET_CSS, WidgetHeader, WidgetShell, WidgetStyleProvider, WorkflowPanel, clearStyleCache, getCssVar, injectStyles, mergeCopilotStyles, mergeWidgetStyles, stylesToCSSVariables, stylesToCssVars, useChat, useConversations, useCopilotStyleContext, useCopilotStyles, useCopilotStyles2 as useCopilotStylesContext, useCrowAPI, usePreviewCopilotStyles, usePreviewWidgetStyles, useVoiceInput, useWidgetStyleContext, useWidgetStyles, useWidgetStyles2 as useWidgetStylesContext, useWorkflow };
6738
7481
  //# sourceMappingURL=index.js.map
6739
7482
  //# sourceMappingURL=index.js.map