@usecrow/ui 0.1.75 → 0.1.77

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 (!isLoadingStyles && !onboardingChecked && (forceOnboarding || onboardingEnabled)) {
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,17 @@ 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
+ endWorkflow(0);
4973
+ }
4974
+ prevOnboardingRef.current = isOnboarding;
4975
+ }, [isOnboarding]);
4779
4976
  useEffect(() => {
4780
4977
  if (!isLoadingStyles) {
4781
4978
  onReady?.();
@@ -5060,7 +5257,59 @@ function CrowWidget({
5060
5257
  setIsCollapsed(!isCollapsed);
5061
5258
  };
5062
5259
  const renderWidgetContent = () => /* @__PURE__ */ jsxs(Fragment, { children: [
5063
- /* @__PURE__ */ jsx(
5260
+ isOnboarding ? /* @__PURE__ */ jsxs(
5261
+ "div",
5262
+ {
5263
+ style: {
5264
+ display: "flex",
5265
+ alignItems: "center",
5266
+ justifyContent: "space-between",
5267
+ padding: "10px 16px",
5268
+ borderBottom: "1px solid var(--crow-border, #e5e7eb)",
5269
+ flexShrink: 0,
5270
+ cursor: variant === "floating" ? "grab" : void 0
5271
+ },
5272
+ onPointerDown: variant === "floating" ? transform.onDragPointerDown : void 0,
5273
+ children: [
5274
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "var(--crow-text, #111827)" }, children: onboardingAgentName || agentName }),
5275
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
5276
+ /* @__PURE__ */ jsx(
5277
+ "button",
5278
+ {
5279
+ onClick: () => {
5280
+ setIsOnboarding(false);
5281
+ chat.resetMessages();
5282
+ },
5283
+ style: {
5284
+ fontSize: 12,
5285
+ color: "#9ca3af",
5286
+ background: "none",
5287
+ border: "none",
5288
+ cursor: "pointer",
5289
+ padding: "4px 8px"
5290
+ },
5291
+ children: "Skip"
5292
+ }
5293
+ ),
5294
+ variant === "floating" && /* @__PURE__ */ jsx(
5295
+ "button",
5296
+ {
5297
+ onClick: () => setIsCollapsed(true),
5298
+ style: {
5299
+ background: "none",
5300
+ border: "none",
5301
+ cursor: "pointer",
5302
+ padding: "4px",
5303
+ color: "#9ca3af",
5304
+ display: "flex"
5305
+ },
5306
+ 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" }) })
5307
+ }
5308
+ )
5309
+ ] })
5310
+ ]
5311
+ }
5312
+ ) : /* @__PURE__ */ jsx(
5064
5313
  WidgetHeader,
5065
5314
  {
5066
5315
  isVerifiedUser,
@@ -5076,82 +5325,92 @@ function CrowWidget({
5076
5325
  contextLabel
5077
5326
  }
5078
5327
  ),
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,
5328
+ isOnboarding && onboardingPhase === "intro" && /* @__PURE__ */ jsx(
5329
+ OnboardingIntroInline,
5090
5330
  {
5091
- workflow: activeWorkflow,
5092
- onExit: handleExitWorkflow
5331
+ lines: onboardingIntroSequence || [],
5332
+ primaryColor: styles.colors.primary,
5333
+ onComplete: () => setOnboardingPhase("chat")
5093
5334
  }
5094
- ) }),
5095
- /* @__PURE__ */ jsx(AnimatePresence, { children: (chat.messages.length > 0 || conversations.isLoadingHistory || pendingConfirmation) && /* @__PURE__ */ jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
5096
- /* @__PURE__ */ jsx(
5097
- MessageList,
5335
+ ),
5336
+ !(isOnboarding && onboardingPhase === "intro") && /* @__PURE__ */ jsxs(Fragment, { children: [
5337
+ /* @__PURE__ */ jsx(AnimatePresence, { children: showConversationList && isVerifiedUser && /* @__PURE__ */ jsx(
5338
+ ConversationList,
5098
5339
  {
5099
- messages: chat.messages,
5100
- activeToolCalls: chat.activeToolCalls,
5101
- isLoadingHistory: conversations.isLoadingHistory,
5102
- isGenerating: chat.isLoading,
5103
- toolRenderers: effectiveToolRenderers,
5104
- onToolConsent: handleToolConsent
5340
+ conversations: conversations.conversations,
5341
+ currentConversationId: chat.conversationId,
5342
+ onSelect: handleSelectConversation,
5343
+ onClose: handleCloseConversationList
5105
5344
  }
5106
- ),
5107
- pendingConfirmation && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
5108
- BrowserUseConfirmation,
5345
+ ) }),
5346
+ /* @__PURE__ */ jsx(AnimatePresence, { children: activeWorkflow && !isOnboarding && /* @__PURE__ */ jsx(
5347
+ WorkflowPanel,
5109
5348
  {
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
- }
5349
+ workflow: activeWorkflow,
5350
+ onExit: handleExitWorkflow
5120
5351
  }
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" })
5352
+ ) }),
5353
+ /* @__PURE__ */ jsx(AnimatePresence, { children: (chat.messages.length > 0 || conversations.isLoadingHistory || pendingConfirmation) && /* @__PURE__ */ jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
5354
+ /* @__PURE__ */ jsx(
5355
+ MessageList,
5356
+ {
5357
+ messages: chat.messages,
5358
+ activeToolCalls: chat.activeToolCalls,
5359
+ isLoadingHistory: conversations.isLoadingHistory,
5360
+ isGenerating: chat.isLoading,
5361
+ toolRenderers: effectiveToolRenderers,
5362
+ onToolConsent: handleToolConsent
5363
+ }
5364
+ ),
5365
+ pendingConfirmation && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
5366
+ BrowserUseConfirmation,
5367
+ {
5368
+ instruction: pendingConfirmation.instruction,
5369
+ onAllow: () => {
5370
+ setIsBrowserUseActive(true);
5371
+ pendingConfirmation.resolve(true);
5372
+ setPendingConfirmation(null);
5373
+ },
5374
+ onDeny: () => {
5375
+ pendingConfirmation.resolve(false);
5376
+ setPendingConfirmation(null);
5377
+ }
5378
+ }
5379
+ ) })
5380
+ ] }) }),
5381
+ /* @__PURE__ */ jsxs("div", { className: "crow-mt-auto crow-w-full", children: [
5382
+ 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: [
5383
+ /* @__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: [
5384
+ /* @__PURE__ */ jsx("circle", { className: "crow-opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
5385
+ /* @__PURE__ */ jsx("path", { className: "crow-opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
5386
+ ] }),
5387
+ /* @__PURE__ */ jsx("span", { className: "crow-font-medium crow-text-[var(--crow-text,#111827)]", children: toolStatus })
5128
5388
  ] }),
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
- )
5389
+ (chat.suggestedActions.length > 0 || !isOnboarding && !chat.isLoading && defaultSuggestedActionsRef.current.length > 0) && /* @__PURE__ */ jsx(
5390
+ SuggestedActions,
5391
+ {
5392
+ actions: chat.suggestedActions.length > 0 ? chat.suggestedActions : defaultSuggestedActionsRef.current,
5393
+ onActionClick: (action) => handleSend(action.message)
5394
+ }
5395
+ ),
5396
+ /* @__PURE__ */ jsx(PoweredByBadge, { apiUrl }),
5397
+ /* @__PURE__ */ jsx(
5398
+ PromptInputBox,
5399
+ {
5400
+ onSend: handleSend,
5401
+ onStop: handleStop,
5402
+ placeholder: "Type your message...",
5403
+ isLoading: chat.isLoading,
5404
+ showStopButton: isBrowserUseActive || !!askUserResolver || !!pendingConfirmation,
5405
+ highlighted: !!askUserResolver,
5406
+ className: "crow-backdrop-blur-md",
5407
+ backendUrl: apiUrl,
5408
+ selectedModel: chat.selectedModel || selectedModelFromAPI,
5409
+ onModelChange: chat.setSelectedModel,
5410
+ availableModels: modelSelectionEnabled ? availableModelsFromAPI : []
5411
+ }
5412
+ )
5413
+ ] })
5155
5414
  ] })
5156
5415
  ] });
5157
5416
  const combinedStyles = useMemo(
@@ -5165,7 +5424,7 @@ ${customCss}` : WIDGET_CSS,
5165
5424
  WidgetStyleProvider,
5166
5425
  {
5167
5426
  styles,
5168
- agentName,
5427
+ agentName: isOnboarding ? onboardingAgentName || agentName : agentName,
5169
5428
  isLoading: isLoadingStyles,
5170
5429
  variant,
5171
5430
  showThinking,
@@ -5462,6 +5721,78 @@ function CopilotContainer({
5462
5721
  )
5463
5722
  ] });
5464
5723
  }
5724
+ function OnboardingIntroInline2({
5725
+ lines,
5726
+ primaryColor,
5727
+ textColor,
5728
+ textMutedColor,
5729
+ onComplete
5730
+ }) {
5731
+ const [lineIndex, setLineIndex] = useState(0);
5732
+ const [charIndex, setCharIndex] = useState(0);
5733
+ const [done, setDone] = useState(false);
5734
+ useEffect(() => {
5735
+ if (lineIndex >= lines.length) {
5736
+ setDone(true);
5737
+ return;
5738
+ }
5739
+ const currentLine = lines[lineIndex];
5740
+ if (charIndex < currentLine.length) {
5741
+ const t = setTimeout(() => setCharIndex((c) => c + 1), 35);
5742
+ return () => clearTimeout(t);
5743
+ } else {
5744
+ const t = setTimeout(() => {
5745
+ setLineIndex((l) => l + 1);
5746
+ setCharIndex(0);
5747
+ }, 500);
5748
+ return () => clearTimeout(t);
5749
+ }
5750
+ }, [lineIndex, charIndex, lines]);
5751
+ const displayedLines = lines.slice(0, lineIndex + 1).map(
5752
+ (line, i) => i < lineIndex ? line : line.slice(0, charIndex)
5753
+ );
5754
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5755
+ /* @__PURE__ */ jsx("div", { style: { minHeight: "4rem", marginBottom: "1.5rem" }, children: displayedLines.map((text, i) => /* @__PURE__ */ jsxs("p", { style: {
5756
+ fontSize: i === 0 ? 18 : 14,
5757
+ fontWeight: i === 0 ? 600 : 400,
5758
+ color: i === 0 ? textColor : textMutedColor,
5759
+ lineHeight: 1.4,
5760
+ margin: "0 0 6px 0"
5761
+ }, children: [
5762
+ text,
5763
+ i === lineIndex && !done && /* @__PURE__ */ jsx("span", { style: {
5764
+ display: "inline-block",
5765
+ width: 2,
5766
+ height: i === 0 ? 18 : 14,
5767
+ backgroundColor: textColor,
5768
+ marginLeft: 2,
5769
+ verticalAlign: "middle",
5770
+ animation: "crow-blink 1s step-end infinite"
5771
+ } })
5772
+ ] }, i)) }),
5773
+ /* @__PURE__ */ jsx(
5774
+ "button",
5775
+ {
5776
+ onClick: onComplete,
5777
+ style: {
5778
+ padding: "8px 24px",
5779
+ borderRadius: 8,
5780
+ backgroundColor: primaryColor,
5781
+ color: "#fff",
5782
+ fontSize: 13,
5783
+ fontWeight: 500,
5784
+ border: "none",
5785
+ cursor: "pointer",
5786
+ opacity: done ? 1 : 0,
5787
+ pointerEvents: done ? "auto" : "none",
5788
+ transition: "opacity 0.5s ease"
5789
+ },
5790
+ children: "Get Started \u2192"
5791
+ }
5792
+ ),
5793
+ /* @__PURE__ */ jsx("style", { children: `@keyframes crow-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }` })
5794
+ ] });
5795
+ }
5465
5796
  function CrowCopilot({
5466
5797
  productId,
5467
5798
  apiUrl = "",
@@ -5485,7 +5816,10 @@ function CrowCopilot({
5485
5816
  getIdentityToken,
5486
5817
  context,
5487
5818
  language,
5488
- contextLabel: contextLabelProp
5819
+ contextLabel: contextLabelProp,
5820
+ forceOnboarding = false,
5821
+ fullscreenTopOffset: _fullscreenTopOffset = 0,
5822
+ mode: _mode
5489
5823
  }) {
5490
5824
  const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
5491
5825
  const effectiveOnToolResult = onToolResult || window.__crow_on_tool_result;
@@ -5503,7 +5837,11 @@ function CrowCopilot({
5503
5837
  toolConsentSettings,
5504
5838
  modelSelectionEnabled,
5505
5839
  availableModels: availableModelsFromAPI,
5506
- initialSuggestions
5840
+ initialSuggestions,
5841
+ onboardingEnabled,
5842
+ onboardingAgentName,
5843
+ onboardingWelcomeMessage,
5844
+ onboardingIntroSequence
5507
5845
  } = useCopilotStyles({
5508
5846
  productId,
5509
5847
  apiUrl,
@@ -5512,6 +5850,20 @@ function CrowCopilot({
5512
5850
  language
5513
5851
  });
5514
5852
  const agentName = agentNameProp ?? agentNameFromAPI ?? title;
5853
+ const [isOnboarding, setIsOnboarding] = useState(false);
5854
+ const [onboardingChecked, setOnboardingChecked] = useState(false);
5855
+ const [onboardingPhase, setOnboardingPhase] = useState("intro");
5856
+ useEffect(() => {
5857
+ if (!isLoadingStyles && !onboardingChecked && (forceOnboarding || onboardingEnabled)) {
5858
+ setIsOnboarding(true);
5859
+ setOnboardingChecked(true);
5860
+ }
5861
+ }, [forceOnboarding, isLoadingStyles, onboardingEnabled, onboardingChecked]);
5862
+ useEffect(() => {
5863
+ if (isOnboarding && !isLoadingStyles && onboardingIntroSequence !== void 0 && onboardingIntroSequence.length === 0) {
5864
+ setOnboardingPhase("chat");
5865
+ }
5866
+ }, [isOnboarding, isLoadingStyles, onboardingIntroSequence]);
5515
5867
  const [toolStatus, setToolStatus] = useState(
5516
5868
  () => window.__crow_tool_status ?? ""
5517
5869
  );
@@ -5692,10 +6044,10 @@ function CrowCopilot({
5692
6044
  };
5693
6045
  }, []);
5694
6046
  useEffect(() => {
5695
- if (initialSuggestions.length > 0 && chat.suggestedActions.length === 0) {
6047
+ if (!isOnboarding && initialSuggestions.length > 0 && chat.suggestedActions.length === 0) {
5696
6048
  chat.setSuggestedActions(initialSuggestions);
5697
6049
  }
5698
- }, [initialSuggestions]);
6050
+ }, [initialSuggestions, isOnboarding]);
5699
6051
  const messagesContainerRef = useRef(null);
5700
6052
  const tabsScrollRef = useRef(null);
5701
6053
  const executeClientToolRef = useRef(null);
@@ -5725,11 +6077,17 @@ function CrowCopilot({
5725
6077
  pendingRestoreConvId.current = "";
5726
6078
  }
5727
6079
  }
6080
+ const effectiveWelcomeMessage = isOnboarding ? onboardingWelcomeMessage || `Hi! I'm ${onboardingAgentName || agentName}. Let me help you get started.` : welcomeMessage;
5728
6081
  const chat = useChat({
5729
6082
  productId,
5730
6083
  apiUrl,
5731
6084
  persistAnonymousConversations,
5732
- welcomeMessage,
6085
+ welcomeMessage: effectiveWelcomeMessage,
6086
+ agentMode: isOnboarding ? "onboarding" : void 0,
6087
+ onOnboardingComplete: (summary) => {
6088
+ console.log("[Crow] Onboarding complete:", summary);
6089
+ setIsOnboarding(false);
6090
+ },
5733
6091
  selectedModel,
5734
6092
  subdomain,
5735
6093
  toolConsentSettings,
@@ -5873,6 +6231,33 @@ function CrowCopilot({
5873
6231
  const { executeClientTool } = useCrowAPI({
5874
6232
  onIdentified: async () => {
5875
6233
  setIsVerifiedUser(true);
6234
+ if (forceOnboarding) {
6235
+ setIsOnboarding(true);
6236
+ setOnboardingChecked(true);
6237
+ } else if (onboardingEnabled && !onboardingChecked) {
6238
+ try {
6239
+ const identityToken = window.__crow_identity_token;
6240
+ if (identityToken) {
6241
+ const res = await fetch(`${apiUrl}/api/chat/resolve-agent`, {
6242
+ method: "POST",
6243
+ headers: { "Content-Type": "application/json" },
6244
+ body: JSON.stringify({
6245
+ product_id: productId,
6246
+ identity_token: identityToken
6247
+ })
6248
+ });
6249
+ if (res.ok) {
6250
+ const data = await res.json();
6251
+ if (data.agent === "onboarding") {
6252
+ setIsOnboarding(true);
6253
+ }
6254
+ }
6255
+ }
6256
+ } catch (e) {
6257
+ console.error("[Crow] resolve-agent failed:", e);
6258
+ }
6259
+ setOnboardingChecked(true);
6260
+ }
5876
6261
  await conversations.loadConversations();
5877
6262
  const savedId = pendingRestoreConvId.current;
5878
6263
  if (savedId && !hasRestoredActiveConvRef.current) {
@@ -5895,6 +6280,17 @@ function CrowCopilot({
5895
6280
  });
5896
6281
  executeClientToolRef.current = executeClientTool;
5897
6282
  submitToolResultRef.current = chat.submitToolResult;
6283
+ const prevOnboardingRef = useRef(isOnboarding);
6284
+ useEffect(() => {
6285
+ if (isOnboarding && !prevOnboardingRef.current) {
6286
+ chat.setSuggestedActions([]);
6287
+ }
6288
+ if (prevOnboardingRef.current && !isOnboarding) {
6289
+ chat.resetMessages();
6290
+ endWorkflow(0);
6291
+ }
6292
+ prevOnboardingRef.current = isOnboarding;
6293
+ }, [isOnboarding]);
5898
6294
  const handleBrowserConfirmation = useCallback(
5899
6295
  (instruction) => {
5900
6296
  return new Promise((resolve) => {
@@ -6235,312 +6631,347 @@ function CrowCopilot({
6235
6631
  "--crow-bg-active": styles.colors.text + "18"
6236
6632
  },
6237
6633
  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,
6634
+ isOnboarding && /* @__PURE__ */ jsxs(Fragment, { children: [
6635
+ /* @__PURE__ */ jsxs(
6636
+ "div",
6447
6637
  {
6448
- conversations: conversations.conversations,
6449
- currentConversationId: chat.conversationId,
6450
- onSelect: handleSelectConversation,
6451
- onClose: handleCloseConversationList
6638
+ className: "crow-flex crow-items-center crow-justify-between crow-border-b crow-px-4 crow-py-2.5",
6639
+ style: { borderColor: styles.colors.border },
6640
+ children: [
6641
+ /* @__PURE__ */ jsx("span", { className: "crow-text-[13px] crow-font-semibold", style: { color: styles.colors.text }, children: onboardingAgentName || agentName }),
6642
+ /* @__PURE__ */ jsx(
6643
+ "button",
6644
+ {
6645
+ onClick: () => {
6646
+ setIsOnboarding(false);
6647
+ },
6648
+ className: "crow-text-xs crow-border-none crow-bg-transparent crow-cursor-pointer crow-px-2 crow-py-1",
6649
+ style: { color: styles.colors.text + "60" },
6650
+ children: "Skip"
6651
+ }
6652
+ )
6653
+ ]
6452
6654
  }
6453
6655
  ),
6454
- showConversationList && !isVerifiedUser && /* @__PURE__ */ jsx(
6455
- "div",
6656
+ 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(
6657
+ OnboardingIntroInline2,
6456
6658
  {
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." })
6659
+ lines: onboardingIntroSequence || [],
6660
+ primaryColor: styles.colors.primary,
6661
+ textColor: styles.colors.text,
6662
+ textMutedColor: styles.colors.text + "80",
6663
+ onComplete: () => setOnboardingPhase("chat")
6460
6664
  }
6461
- )
6665
+ ) })
6462
6666
  ] }),
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,
6667
+ !(isOnboarding && onboardingPhase === "intro") && /* @__PURE__ */ jsxs(Fragment, { children: [
6668
+ !isOnboarding && /* @__PURE__ */ jsxs(
6669
+ "div",
6473
6670
  {
6474
- messages: chat.messages,
6475
- activeToolCalls: chat.activeToolCalls,
6476
- isLoadingHistory: conversations.isLoadingHistory,
6477
- isGenerating: chat.isLoading,
6478
- toolRenderers: effectiveToolRenderers,
6479
- onToolConsent: handleToolConsent
6671
+ className: "crow-flex crow-items-stretch crow-border-b crow-min-h-[40px]",
6672
+ style: { borderColor: styles.colors.border },
6673
+ children: [
6674
+ /* @__PURE__ */ jsx(
6675
+ "div",
6676
+ {
6677
+ ref: tabsScrollRef,
6678
+ className: "crow-flex crow-items-stretch crow-flex-1 crow-min-w-0 crow-overflow-x-auto",
6679
+ style: {
6680
+ scrollbarWidth: "none",
6681
+ msOverflowStyle: "none"
6682
+ },
6683
+ onScroll: handleTabsScroll,
6684
+ children: tabs.map((tab, idx) => {
6685
+ const isActive = activeTabId === tab.id;
6686
+ const isHovered = hoveredTabId === tab.id;
6687
+ const isCloseable = tab.type !== "new" && (tab.type !== "local" || localTabs.length > 1);
6688
+ return /* @__PURE__ */ jsxs(
6689
+ "div",
6690
+ {
6691
+ 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",
6692
+ style: {
6693
+ color: isActive ? styles.colors.text : styles.colors.text + "80",
6694
+ fontWeight: isActive ? 500 : void 0,
6695
+ maxWidth: "180px",
6696
+ borderRight: idx < tabs.length - 1 ? `1px solid ${styles.colors.border}` : "none",
6697
+ paddingLeft: "16px",
6698
+ paddingRight: isCloseable ? "8px" : "16px"
6699
+ },
6700
+ title: tab.name,
6701
+ onMouseEnter: () => setHoveredTabId(tab.id),
6702
+ onMouseLeave: () => setHoveredTabId(null),
6703
+ onClick: () => {
6704
+ if (tab.type === "new") {
6705
+ handleNewChat();
6706
+ return;
6707
+ }
6708
+ if (tab.type === "server") {
6709
+ handleSelectConversation(tab.id);
6710
+ return;
6711
+ }
6712
+ handleSelectLocalTab(tab.id);
6713
+ },
6714
+ children: [
6715
+ /* @__PURE__ */ jsx(
6716
+ "span",
6717
+ {
6718
+ className: "crow-block crow-truncate",
6719
+ style: { maxWidth: isCloseable ? "112px" : "128px" },
6720
+ children: tab.name
6721
+ }
6722
+ ),
6723
+ isCloseable && /* @__PURE__ */ jsx(
6724
+ "span",
6725
+ {
6726
+ className: "crow-rounded crow-p-0.5 crow-flex-shrink-0 crow-inline-flex crow-items-center crow-justify-center crow-transition-opacity",
6727
+ style: {
6728
+ marginLeft: "6px",
6729
+ opacity: isHovered ? 1 : 0,
6730
+ pointerEvents: isHovered ? "auto" : "none"
6731
+ },
6732
+ onClick: (e) => {
6733
+ e.stopPropagation();
6734
+ handleCloseTab(tab.id, tab.type);
6735
+ },
6736
+ role: "button",
6737
+ "aria-label": `Close ${tab.name}`,
6738
+ children: /* @__PURE__ */ jsx(TabCloseIcon, { className: "crow-w-3 crow-h-3", style: { color: styles.colors.text + "80" } })
6739
+ }
6740
+ ),
6741
+ isActive && /* @__PURE__ */ jsx(
6742
+ "span",
6743
+ {
6744
+ className: "crow-absolute crow-bottom-0 crow-left-0 crow-right-0",
6745
+ style: {
6746
+ height: "2px",
6747
+ background: styles.colors.primary || "#2563eb"
6748
+ }
6749
+ }
6750
+ )
6751
+ ]
6752
+ },
6753
+ `${tab.id}-${idx}`
6754
+ );
6755
+ })
6756
+ }
6757
+ ),
6758
+ /* @__PURE__ */ jsxs(
6759
+ "div",
6760
+ {
6761
+ className: "crow-flex crow-items-center crow-flex-shrink-0 crow-border-l",
6762
+ style: { borderColor: styles.colors.border },
6763
+ children: [
6764
+ /* @__PURE__ */ jsx(
6765
+ "button",
6766
+ {
6767
+ onClick: handleNewChat,
6768
+ className: "crow-p-2 crow-transition-colors crow-rounded",
6769
+ style: { color: styles.colors.text + "80" },
6770
+ onMouseEnter: (e) => {
6771
+ e.currentTarget.style.background = styles.colors.text + "10";
6772
+ },
6773
+ onMouseLeave: (e) => {
6774
+ e.currentTarget.style.background = "transparent";
6775
+ },
6776
+ "aria-label": "New Chat",
6777
+ title: "New Chat",
6778
+ children: /* @__PURE__ */ jsx(PlusIcon, { className: "crow-w-4 crow-h-4" })
6779
+ }
6780
+ ),
6781
+ /* @__PURE__ */ jsx(
6782
+ "button",
6783
+ {
6784
+ onClick: handleToggleHistory,
6785
+ disabled: !isVerifiedUser,
6786
+ "aria-disabled": !isVerifiedUser,
6787
+ className: `crow-p-2 crow-transition-colors crow-rounded ${!isVerifiedUser ? "crow-opacity-40 crow-cursor-not-allowed" : ""}`,
6788
+ style: {
6789
+ color: styles.colors.text + "80",
6790
+ background: showConversationList ? styles.colors.text + "10" : "transparent"
6791
+ },
6792
+ onMouseEnter: (e) => {
6793
+ if (isVerifiedUser) e.currentTarget.style.background = styles.colors.text + "10";
6794
+ },
6795
+ onMouseLeave: (e) => {
6796
+ if (!showConversationList) e.currentTarget.style.background = "transparent";
6797
+ },
6798
+ "aria-label": "Conversation History",
6799
+ title: isVerifiedUser ? "Conversation History" : "Sign in to view history",
6800
+ children: /* @__PURE__ */ jsx(HistoryIcon, { className: "crow-w-4 crow-h-4" })
6801
+ }
6802
+ ),
6803
+ canScrollRight && /* @__PURE__ */ jsx(
6804
+ "button",
6805
+ {
6806
+ onClick: handleScrollRight,
6807
+ className: "crow-p-2 crow-transition-colors crow-rounded",
6808
+ style: { color: styles.colors.text + "80" },
6809
+ onMouseEnter: (e) => {
6810
+ e.currentTarget.style.background = styles.colors.text + "10";
6811
+ },
6812
+ onMouseLeave: (e) => {
6813
+ e.currentTarget.style.background = "transparent";
6814
+ },
6815
+ "aria-label": "Scroll tabs",
6816
+ title: "Scroll tabs",
6817
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "crow-w-4 crow-h-4" })
6818
+ }
6819
+ ),
6820
+ (forceShowClose ?? showClose) && (overrideOnClose ?? onClose) && /* @__PURE__ */ jsx(
6821
+ "button",
6822
+ {
6823
+ onClick: overrideOnClose ?? onClose,
6824
+ className: "crow-p-2 crow-transition-colors crow-rounded",
6825
+ style: { color: styles.colors.text + "80" },
6826
+ onMouseEnter: (e) => {
6827
+ e.currentTarget.style.background = styles.colors.text + "10";
6828
+ },
6829
+ onMouseLeave: (e) => {
6830
+ e.currentTarget.style.background = "transparent";
6831
+ },
6832
+ "aria-label": "Close",
6833
+ children: /* @__PURE__ */ jsx(CloseIcon, { className: "crow-w-4 crow-h-4" })
6834
+ }
6835
+ )
6836
+ ]
6837
+ }
6838
+ )
6839
+ ]
6480
6840
  }
6481
6841
  ),
6482
- pendingConfirmation && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
6483
- BrowserUseConfirmation,
6842
+ contextLabel && /* @__PURE__ */ jsxs(
6843
+ "div",
6484
6844
  {
6485
- instruction: pendingConfirmation.instruction,
6486
- onAllow: () => {
6487
- pendingConfirmation.resolve(true);
6488
- setPendingConfirmation(null);
6845
+ className: "crow-flex crow-items-center crow-gap-1.5 crow-px-3 crow-py-1.5 crow-border-b crow-text-xs",
6846
+ style: {
6847
+ color: styles.colors.text + "80",
6848
+ borderColor: styles.colors.border
6489
6849
  },
6490
- onDeny: () => {
6491
- pendingConfirmation.resolve(false);
6492
- setPendingConfirmation(null);
6850
+ children: [
6851
+ /* @__PURE__ */ jsxs(
6852
+ "svg",
6853
+ {
6854
+ xmlns: "http://www.w3.org/2000/svg",
6855
+ width: "12",
6856
+ height: "12",
6857
+ viewBox: "0 0 24 24",
6858
+ fill: "none",
6859
+ stroke: "currentColor",
6860
+ strokeWidth: "2",
6861
+ strokeLinecap: "round",
6862
+ strokeLinejoin: "round",
6863
+ className: "crow-shrink-0",
6864
+ children: [
6865
+ /* @__PURE__ */ jsx("path", { d: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" }),
6866
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "10", r: "3" })
6867
+ ]
6868
+ }
6869
+ ),
6870
+ /* @__PURE__ */ jsx("span", { className: "crow-truncate", children: contextLabel })
6871
+ ]
6872
+ }
6873
+ ),
6874
+ /* @__PURE__ */ jsxs(AnimatePresence, { children: [
6875
+ showConversationList && isVerifiedUser && /* @__PURE__ */ jsx(
6876
+ ConversationList,
6877
+ {
6878
+ conversations: conversations.conversations,
6879
+ currentConversationId: chat.conversationId,
6880
+ onSelect: handleSelectConversation,
6881
+ onClose: handleCloseConversationList
6493
6882
  }
6883
+ ),
6884
+ showConversationList && !isVerifiedUser && /* @__PURE__ */ jsx(
6885
+ "div",
6886
+ {
6887
+ className: "crow-mb-3 crow-rounded-xl crow-border crow-p-4",
6888
+ style: { background: styles.colors.text + "08", borderColor: styles.colors.border },
6889
+ children: /* @__PURE__ */ jsx("div", { className: "crow-text-sm", style: { color: styles.colors.text + "99" }, children: "Sign in to view conversation history." })
6890
+ }
6891
+ )
6892
+ ] }),
6893
+ /* @__PURE__ */ jsx(AnimatePresence, { children: activeWorkflow && !isOnboarding && /* @__PURE__ */ jsx(
6894
+ WorkflowPanel,
6895
+ {
6896
+ workflow: activeWorkflow,
6897
+ onExit: handleExitWorkflow
6494
6898
  }
6495
6899
  ) }),
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);
6900
+ /* @__PURE__ */ jsxs(MessagesContainer, { ref: messagesContainerRef, children: [
6901
+ /* @__PURE__ */ jsx(
6902
+ MessageList,
6903
+ {
6904
+ messages: chat.messages,
6905
+ activeToolCalls: chat.activeToolCalls,
6906
+ isLoadingHistory: conversations.isLoadingHistory,
6907
+ isGenerating: chat.isLoading,
6908
+ toolRenderers: effectiveToolRenderers,
6909
+ onToolConsent: handleToolConsent
6504
6910
  }
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)
6911
+ ),
6912
+ pendingConfirmation && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
6913
+ BrowserUseConfirmation,
6914
+ {
6915
+ instruction: pendingConfirmation.instruction,
6916
+ onAllow: () => {
6917
+ pendingConfirmation.resolve(true);
6918
+ setPendingConfirmation(null);
6919
+ },
6920
+ onDeny: () => {
6921
+ pendingConfirmation.resolve(false);
6922
+ setPendingConfirmation(null);
6526
6923
  }
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 : []
6924
+ }
6925
+ ) }),
6926
+ askUserResolver && browserQuestion && /* @__PURE__ */ jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsx(
6927
+ BrowserUseQuestion,
6928
+ {
6929
+ question: browserQuestion,
6930
+ onSubmit: (answer) => {
6931
+ askUserResolver.resolve(answer);
6932
+ setAskUserResolver(null);
6933
+ setBrowserQuestion(null);
6539
6934
  }
6540
- )
6541
- ]
6542
- }
6543
- )
6935
+ }
6936
+ ) })
6937
+ ] }),
6938
+ /* @__PURE__ */ jsxs(
6939
+ "div",
6940
+ {
6941
+ className: "crow-p-3 crow-border-t",
6942
+ style: { borderColor: styles.colors.border },
6943
+ children: [
6944
+ 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: [
6945
+ /* @__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: [
6946
+ /* @__PURE__ */ jsx("circle", { className: "crow-opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
6947
+ /* @__PURE__ */ jsx("path", { className: "crow-opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
6948
+ ] }),
6949
+ /* @__PURE__ */ jsx("span", { className: "crow-font-medium crow-text-[var(--crow-text,#111827)]", children: toolStatus })
6950
+ ] }),
6951
+ (chat.suggestedActions.length > 0 || !isOnboarding && !chat.isLoading && defaultSuggestedActionsRef.current.length > 0) && /* @__PURE__ */ jsx(
6952
+ SuggestedActions,
6953
+ {
6954
+ actions: chat.suggestedActions.length > 0 ? chat.suggestedActions : defaultSuggestedActionsRef.current,
6955
+ onActionClick: (action) => handleSend(action.message)
6956
+ }
6957
+ ),
6958
+ styles.branding.showPoweredBy && /* @__PURE__ */ jsx(PoweredByBadge, { apiUrl }),
6959
+ /* @__PURE__ */ jsx(
6960
+ PromptInputBox,
6961
+ {
6962
+ onSend: handleSend,
6963
+ onStop: handleStop,
6964
+ placeholder: "Ask anything...",
6965
+ isLoading: chat.isLoading,
6966
+ selectedModel: chat.selectedModel || selectedModel,
6967
+ onModelChange: chat.setSelectedModel,
6968
+ availableModels: modelSelectionEnabled ? availableModelsFromAPI : []
6969
+ }
6970
+ )
6971
+ ]
6972
+ }
6973
+ )
6974
+ ] })
6544
6975
  ]
6545
6976
  }
6546
6977
  )
@@ -6562,7 +6993,7 @@ function CrowCopilot({
6562
6993
  const edgeSide = isRight ? "left" : "right";
6563
6994
  const toggleIconColor = styles.colors.text + "80";
6564
6995
  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: [
6996
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { style: { position: "relative", flexShrink: 0, height: "100%" }, children: [
6566
6997
  /* @__PURE__ */ jsx(
6567
6998
  "button",
6568
6999
  {
@@ -6606,7 +7037,7 @@ function CrowCopilot({
6606
7037
  children: /* @__PURE__ */ jsx(ShadowContainer, { styles: WIDGET_CSS, children: renderCopilotContent(void 0, false, "100%") })
6607
7038
  }
6608
7039
  )
6609
- ] });
7040
+ ] }) });
6610
7041
  }
6611
7042
  function PlusIcon({ className }) {
6612
7043
  return /* @__PURE__ */ jsxs(
@@ -6712,6 +7143,320 @@ function CloseIcon({ className }) {
6712
7143
  }
6713
7144
  );
6714
7145
  }
7146
+ function IntroSequence({ lines, onComplete, onSkip, primaryColor }) {
7147
+ const [lineIndex, setLineIndex] = useState(0);
7148
+ const [charIndex, setCharIndex] = useState(0);
7149
+ const [done, setDone] = useState(false);
7150
+ useEffect(() => {
7151
+ if (lineIndex >= lines.length) {
7152
+ setDone(true);
7153
+ return;
7154
+ }
7155
+ const currentLine = lines[lineIndex];
7156
+ if (charIndex < currentLine.length) {
7157
+ const t = setTimeout(() => setCharIndex((c) => c + 1), 35);
7158
+ return () => clearTimeout(t);
7159
+ } else {
7160
+ const t = setTimeout(() => {
7161
+ setLineIndex((l) => l + 1);
7162
+ setCharIndex(0);
7163
+ }, 500);
7164
+ return () => clearTimeout(t);
7165
+ }
7166
+ }, [lineIndex, charIndex, lines]);
7167
+ const displayedLines = lines.slice(0, lineIndex + 1).map((line, i) => {
7168
+ if (i < lineIndex) return line;
7169
+ return line.slice(0, charIndex);
7170
+ });
7171
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100%", padding: "2rem" }, children: [
7172
+ /* @__PURE__ */ jsx(
7173
+ "button",
7174
+ {
7175
+ onClick: onSkip,
7176
+ style: {
7177
+ position: "absolute",
7178
+ top: 20,
7179
+ right: 24,
7180
+ fontSize: 14,
7181
+ color: "#9ca3af",
7182
+ background: "none",
7183
+ border: "none",
7184
+ cursor: "pointer",
7185
+ padding: "4px 8px"
7186
+ },
7187
+ children: "Skip"
7188
+ }
7189
+ ),
7190
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", minHeight: "5rem", marginBottom: "2.5rem" }, children: displayedLines.map((text, i) => /* @__PURE__ */ jsxs(
7191
+ "p",
7192
+ {
7193
+ style: {
7194
+ fontSize: i === 0 ? 30 : 18,
7195
+ fontWeight: i === 0 ? 600 : 400,
7196
+ color: i === 0 ? "#111827" : "#6b7280",
7197
+ lineHeight: 1.4,
7198
+ margin: "0 0 8px 0"
7199
+ },
7200
+ children: [
7201
+ text,
7202
+ i === lineIndex && !done && /* @__PURE__ */ jsx(
7203
+ "span",
7204
+ {
7205
+ style: {
7206
+ display: "inline-block",
7207
+ width: 2,
7208
+ height: i === 0 ? 28 : 18,
7209
+ backgroundColor: "#111827",
7210
+ marginLeft: 2,
7211
+ verticalAlign: "middle",
7212
+ animation: "crow-blink 1s step-end infinite"
7213
+ }
7214
+ }
7215
+ )
7216
+ ]
7217
+ },
7218
+ i
7219
+ )) }),
7220
+ /* @__PURE__ */ jsx(
7221
+ "button",
7222
+ {
7223
+ onClick: onComplete,
7224
+ style: {
7225
+ padding: "10px 32px",
7226
+ borderRadius: 12,
7227
+ backgroundColor: primaryColor,
7228
+ color: "#fff",
7229
+ fontSize: 15,
7230
+ fontWeight: 500,
7231
+ border: "none",
7232
+ cursor: "pointer",
7233
+ opacity: done ? 1 : 0,
7234
+ pointerEvents: done ? "auto" : "none",
7235
+ transition: "opacity 0.5s ease"
7236
+ },
7237
+ children: "Get Started \u2192"
7238
+ }
7239
+ ),
7240
+ /* @__PURE__ */ jsx("style", { children: `
7241
+ @keyframes crow-blink {
7242
+ 0%, 100% { opacity: 1; }
7243
+ 50% { opacity: 0; }
7244
+ }
7245
+ ` })
7246
+ ] });
7247
+ }
7248
+ function CrowOnboarding({
7249
+ productId,
7250
+ apiUrl,
7251
+ subdomain,
7252
+ agentName,
7253
+ welcomeMessage,
7254
+ introSequence,
7255
+ topOffset = 0,
7256
+ onComplete,
7257
+ language,
7258
+ styles: preResolvedStyles,
7259
+ getIdentityToken
7260
+ }) {
7261
+ const [phase, setPhase] = useState(
7262
+ introSequence && introSequence.length > 0 ? "intro" : "chat"
7263
+ );
7264
+ const [isDismissing, setIsDismissing] = useState(false);
7265
+ const bottomRef = useRef(null);
7266
+ const styles = useMemo(
7267
+ () => preResolvedStyles || mergeWidgetStyles(void 0, void 0),
7268
+ [preResolvedStyles]
7269
+ );
7270
+ const cssVars = useMemo(
7271
+ () => stylesToCssVars(styles),
7272
+ [styles]
7273
+ );
7274
+ const dismiss = useCallback(() => {
7275
+ setIsDismissing(true);
7276
+ setTimeout(() => onComplete(), 400);
7277
+ }, [onComplete]);
7278
+ const handleOnboardingComplete = useCallback(
7279
+ (summary) => {
7280
+ console.log("[Crow] Onboarding complete:", summary);
7281
+ dismiss();
7282
+ },
7283
+ [dismiss]
7284
+ );
7285
+ const chat = useChat({
7286
+ productId,
7287
+ apiUrl,
7288
+ subdomain,
7289
+ welcomeMessage: welcomeMessage || `Hi! I'm ${agentName}. Let me help you get started.`,
7290
+ agentMode: "onboarding",
7291
+ onOnboardingComplete: handleOnboardingComplete,
7292
+ language
7293
+ });
7294
+ useEffect(() => {
7295
+ bottomRef.current?.scrollIntoView({ behavior: "smooth" });
7296
+ }, [chat.messages, chat.isLoading]);
7297
+ const handleSend = useCallback(
7298
+ (content) => {
7299
+ chat.sendMessage(content);
7300
+ },
7301
+ [chat]
7302
+ );
7303
+ const handleStop = useCallback(() => {
7304
+ chat.stopGeneration();
7305
+ }, [chat]);
7306
+ const handleSuggestedActionClick = useCallback(
7307
+ (action) => {
7308
+ chat.sendMessage(action.message);
7309
+ },
7310
+ [chat]
7311
+ );
7312
+ useEffect(() => {
7313
+ const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
7314
+ if (!effectiveGetIdentityToken) return;
7315
+ let cancelled = false;
7316
+ const identify = async () => {
7317
+ try {
7318
+ const token = await effectiveGetIdentityToken();
7319
+ if (!cancelled && token) {
7320
+ window.__crow_identity_token = token;
7321
+ }
7322
+ } catch (e) {
7323
+ console.error("[Crow] Onboarding getIdentityToken failed:", e);
7324
+ }
7325
+ };
7326
+ identify();
7327
+ return () => {
7328
+ cancelled = true;
7329
+ };
7330
+ }, [getIdentityToken]);
7331
+ const renderChat = () => /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", background: "#ffffff" }, children: [
7332
+ /* @__PURE__ */ jsxs("div", { style: {
7333
+ display: "flex",
7334
+ alignItems: "center",
7335
+ justifyContent: "space-between",
7336
+ padding: "12px 24px",
7337
+ borderBottom: "1px solid #f3f4f6",
7338
+ flexShrink: 0
7339
+ }, children: [
7340
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
7341
+ /* @__PURE__ */ jsx("div", { style: {
7342
+ width: 28,
7343
+ height: 28,
7344
+ borderRadius: "50%",
7345
+ backgroundColor: styles.colors.primary,
7346
+ display: "flex",
7347
+ alignItems: "center",
7348
+ justifyContent: "center",
7349
+ color: "#fff",
7350
+ fontSize: 13,
7351
+ fontWeight: 600,
7352
+ flexShrink: 0
7353
+ }, children: agentName.charAt(0).toUpperCase() }),
7354
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 14, fontWeight: 600, color: "#111827" }, children: agentName })
7355
+ ] }),
7356
+ /* @__PURE__ */ jsx(
7357
+ "button",
7358
+ {
7359
+ onClick: dismiss,
7360
+ style: {
7361
+ fontSize: 13,
7362
+ color: "#9ca3af",
7363
+ background: "none",
7364
+ border: "none",
7365
+ cursor: "pointer",
7366
+ padding: "4px 8px"
7367
+ },
7368
+ children: "Skip"
7369
+ }
7370
+ )
7371
+ ] }),
7372
+ /* @__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: [
7373
+ /* @__PURE__ */ jsx(
7374
+ WidgetStyleProvider,
7375
+ {
7376
+ styles,
7377
+ agentName,
7378
+ isLoading: false,
7379
+ variant: "embedded",
7380
+ children: /* @__PURE__ */ jsx(
7381
+ MessageList,
7382
+ {
7383
+ messages: chat.messages,
7384
+ activeToolCalls: chat.activeToolCalls,
7385
+ isLoadingHistory: false,
7386
+ isGenerating: chat.isLoading
7387
+ }
7388
+ )
7389
+ }
7390
+ ),
7391
+ /* @__PURE__ */ jsx("div", { ref: bottomRef })
7392
+ ] }) }),
7393
+ 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(
7394
+ WidgetStyleProvider,
7395
+ {
7396
+ styles,
7397
+ agentName,
7398
+ isLoading: false,
7399
+ variant: "embedded",
7400
+ children: /* @__PURE__ */ jsx(
7401
+ SuggestedActions,
7402
+ {
7403
+ actions: chat.suggestedActions,
7404
+ onActionClick: handleSuggestedActionClick
7405
+ }
7406
+ )
7407
+ }
7408
+ ) }),
7409
+ /* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid #f3f4f6", flexShrink: 0 }, children: [
7410
+ /* @__PURE__ */ jsx("div", { className: "crow-widget-root", style: { ...cssVars, maxWidth: 560, margin: "0 auto", padding: "12px 16px" }, children: /* @__PURE__ */ jsx(
7411
+ WidgetStyleProvider,
7412
+ {
7413
+ styles,
7414
+ agentName,
7415
+ isLoading: false,
7416
+ variant: "embedded",
7417
+ children: /* @__PURE__ */ jsx(
7418
+ PromptInputBox,
7419
+ {
7420
+ onSend: handleSend,
7421
+ onStop: handleStop,
7422
+ placeholder: "Type your message...",
7423
+ isLoading: chat.isLoading
7424
+ }
7425
+ )
7426
+ }
7427
+ ) }),
7428
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", padding: "0 0 10px" }, children: /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: "#d1d5db" }, children: "Powered by Crow" }) })
7429
+ ] })
7430
+ ] });
7431
+ return /* @__PURE__ */ jsx(ShadowContainer, { styles: WIDGET_CSS, hostId: "crow-onboarding-host", children: /* @__PURE__ */ jsx(
7432
+ motion.div,
7433
+ {
7434
+ style: {
7435
+ position: "fixed",
7436
+ top: topOffset,
7437
+ left: 0,
7438
+ right: 0,
7439
+ bottom: 0,
7440
+ zIndex: 999999,
7441
+ background: "#ffffff",
7442
+ fontFamily: styles.typography.fontFamily || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
7443
+ fontSize: 14
7444
+ },
7445
+ initial: { opacity: 0 },
7446
+ animate: { opacity: isDismissing ? 0 : 1 },
7447
+ transition: { duration: 0.35 },
7448
+ children: phase === "intro" ? /* @__PURE__ */ jsx(
7449
+ IntroSequence,
7450
+ {
7451
+ lines: introSequence || [],
7452
+ onComplete: () => setPhase("chat"),
7453
+ onSkip: dismiss,
7454
+ primaryColor: styles.colors.primary
7455
+ }
7456
+ ) : renderChat()
7457
+ }
7458
+ ) });
7459
+ }
6715
7460
  var CrowContext = createContext(null);
6716
7461
  function CrowProvider({
6717
7462
  children,
@@ -6734,6 +7479,6 @@ function CrowProvider({
6734
7479
  return /* @__PURE__ */ jsx(CrowContext.Provider, { value, children });
6735
7480
  }
6736
7481
 
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 };
7482
+ 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
7483
  //# sourceMappingURL=index.js.map
6739
7484
  //# sourceMappingURL=index.js.map