@agent-native/toolkit 0.221.0-same-host-mcp-20261027-20261027081850 → 0.221.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-native.eject.json +16 -1
- package/dist/app/agentkit/react/components.d.ts +5 -3
- package/dist/app/agentkit/react/components.d.ts.map +1 -1
- package/dist/app/agentkit/react/components.js +103 -42
- package/dist/app/agentkit/react/components.js.map +1 -1
- package/dist/app/agentkit/react/styles.css +93 -65
- package/dist/app/agentkit/react/voice-transcripts.d.ts +22 -1
- package/dist/app/agentkit/react/voice-transcripts.d.ts.map +1 -1
- package/dist/app/agentkit/react/voice-transcripts.js +209 -8
- package/dist/app/agentkit/react/voice-transcripts.js.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/AgentKitAssistantChat.js +55 -40
- package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts +1 -0
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.js +18 -6
- package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/index.js +1 -1
- package/dist/app/chat/agentkit-chat/index.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +5 -1
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/app/chat/composer/runtime-adapters.js +2 -0
- package/dist/app/chat/composer/runtime-adapters.js.map +1 -1
- package/dist/app/chat/reply-connection-suggestion.d.ts +29 -0
- package/dist/app/chat/reply-connection-suggestion.d.ts.map +1 -0
- package/dist/app/chat/reply-connection-suggestion.js +42 -0
- package/dist/app/chat/reply-connection-suggestion.js.map +1 -0
- package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ar-SA.js +7 -0
- package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/de-DE.js +7 -0
- package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
- package/dist/app/i18n/catalogs/en-US.d.ts +7 -0
- package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/en-US.js +7 -0
- package/dist/app/i18n/catalogs/en-US.js.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/es-ES.js +7 -0
- package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/fr-FR.js +7 -0
- package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/hi-IN.js +7 -0
- package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ja-JP.js +7 -0
- package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/ko-KR.js +7 -0
- package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/pt-BR.js +7 -0
- package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-CN.js +7 -0
- package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
- package/dist/app/i18n/catalogs/zh-TW.js +7 -0
- package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
- package/dist/app/mcp-approval/McpApprovalReview.d.ts +25 -0
- package/dist/app/mcp-approval/McpApprovalReview.d.ts.map +1 -0
- package/dist/app/mcp-approval/McpApprovalReview.js +342 -0
- package/dist/app/mcp-approval/McpApprovalReview.js.map +1 -0
- package/dist/app/onboarding/FirstRunOnboarding.d.ts.map +1 -1
- package/dist/app/onboarding/FirstRunOnboarding.js +299 -71
- package/dist/app/onboarding/FirstRunOnboarding.js.map +1 -1
- package/dist/app/onboarding/GettingStartedCard.js +1 -1
- package/dist/app/onboarding/GettingStartedCard.js.map +1 -1
- package/dist/app/onboarding/first-run-builder-credits-flag.d.ts +2 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.d.ts.map +1 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.js +8 -0
- package/dist/app/onboarding/first-run-builder-credits-flag.js.map +1 -0
- package/dist/app/providers/AppProviders.d.ts.map +1 -1
- package/dist/app/providers/AppProviders.js +14 -1
- package/dist/app/providers/AppProviders.js.map +1 -1
- package/dist/app/resources/McpConnectionSuggestion.d.ts +2 -4
- package/dist/app/resources/McpConnectionSuggestion.d.ts.map +1 -1
- package/dist/app/resources/McpConnectionSuggestion.js +59 -36
- package/dist/app/resources/McpConnectionSuggestion.js.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.d.ts.map +1 -1
- package/dist/app/settings/account/PreferencesSettings.js +14 -1
- package/dist/app/settings/account/PreferencesSettings.js.map +1 -1
- package/dist/app/settings/account/ThemeFamilySettings.js +2 -2
- package/dist/app/settings/account/ThemeFamilySettings.js.map +1 -1
- package/dist/app/settings/account/search-entries.d.ts +1 -0
- package/dist/app/settings/account/search-entries.d.ts.map +1 -1
- package/dist/app/settings/account/search-entries.js +5 -0
- package/dist/app/settings/account/search-entries.js.map +1 -1
- package/dist/app/settings/shell/SettingsShell.d.ts.map +1 -1
- package/dist/app/settings/shell/SettingsShell.js +26 -2
- package/dist/app/settings/shell/SettingsShell.js.map +1 -1
- package/dist/app/shared/AppShellSkeleton.d.ts.map +1 -1
- package/dist/app/shared/AppShellSkeleton.js +4 -10
- package/dist/app/shared/AppShellSkeleton.js.map +1 -1
- package/dist/app/shared/EnvironmentBadge.d.ts +2 -1
- package/dist/app/shared/EnvironmentBadge.d.ts.map +1 -1
- package/dist/app/shared/EnvironmentBadge.js +2 -3
- package/dist/app/shared/EnvironmentBadge.js.map +1 -1
- package/dist/app/shared/is-builder-io-employee.d.ts +8 -0
- package/dist/app/shared/is-builder-io-employee.d.ts.map +1 -0
- package/dist/app/shared/is-builder-io-employee.js +10 -0
- package/dist/app/shared/is-builder-io-employee.js.map +1 -0
- package/dist/app/styles/agent-conversation.css +30 -17
- package/dist/app/styles/theme-families.css +22 -5
- package/dist/app/styles/tokens/agent-kit.css +3 -3
- package/dist/composer/PromptComposer.d.ts +15 -3
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +74 -16
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/RealtimeVoiceMode.d.ts +7 -0
- package/dist/composer/RealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/RealtimeVoiceMode.js +9 -2
- package/dist/composer/RealtimeVoiceMode.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +7 -0
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +12 -4
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/composer/VoiceButton.d.ts +2 -0
- package/dist/composer/VoiceButton.d.ts.map +1 -1
- package/dist/composer/VoiceButton.js +5 -4
- package/dist/composer/VoiceButton.js.map +1 -1
- package/dist/composer/index.d.ts +2 -2
- package/dist/composer/index.d.ts.map +1 -1
- package/dist/composer/index.js +1 -1
- package/dist/composer/index.js.map +1 -1
- package/dist/composer/prompt-attachments.d.ts +20 -0
- package/dist/composer/prompt-attachments.d.ts.map +1 -1
- package/dist/composer/prompt-attachments.js +188 -11
- package/dist/composer/prompt-attachments.js.map +1 -1
- package/dist/composer/realtime-voice-transcript.d.ts +27 -0
- package/dist/composer/realtime-voice-transcript.d.ts.map +1 -1
- package/dist/composer/realtime-voice-transcript.js +34 -1
- package/dist/composer/realtime-voice-transcript.js.map +1 -1
- package/dist/composer/realtime-voice-turn-metrics.d.ts +43 -0
- package/dist/composer/realtime-voice-turn-metrics.d.ts.map +1 -0
- package/dist/composer/realtime-voice-turn-metrics.js +132 -0
- package/dist/composer/realtime-voice-turn-metrics.js.map +1 -0
- package/dist/composer/runtime-adapters.d.ts +4 -1
- package/dist/composer/runtime-adapters.d.ts.map +1 -1
- package/dist/composer/runtime-adapters.js +2 -1
- package/dist/composer/runtime-adapters.js.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.d.ts +61 -9
- package/dist/composer/useRealtimeVoiceMode.d.ts.map +1 -1
- package/dist/composer/useRealtimeVoiceMode.js +536 -99
- package/dist/composer/useRealtimeVoiceMode.js.map +1 -1
- package/dist/composer/voice-chat-icon.d.ts +7 -0
- package/dist/composer/voice-chat-icon.d.ts.map +1 -0
- package/dist/composer/voice-chat-icon.js +14 -0
- package/dist/composer/voice-chat-icon.js.map +1 -0
- package/dist/editor/DragHandle.d.ts +12 -1
- package/dist/editor/DragHandle.d.ts.map +1 -1
- package/dist/editor/DragHandle.js +165 -41
- package/dist/editor/DragHandle.js.map +1 -1
- package/dist/editor/RegistryBlockNode.d.ts +20 -0
- package/dist/editor/RegistryBlockNode.d.ts.map +1 -1
- package/dist/editor/RegistryBlockNode.js +58 -13
- package/dist/editor/RegistryBlockNode.js.map +1 -1
- package/dist/editor/index.d.ts +2 -2
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +1 -1
- package/dist/editor/index.js.map +1 -1
- package/dist/styles.css +2 -0
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +5 -1
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/package.json +14 -4
- package/src/app/agentkit/react/components.regenerate-readiness.spec.tsx +3 -1
- package/src/app/agentkit/react/components.spec.tsx +24 -4
- package/src/app/agentkit/react/components.tsx +174 -44
- package/src/app/agentkit/react/composer-context.spec.tsx +3 -0
- package/src/app/agentkit/react/disclosures.spec.tsx +124 -0
- package/src/app/agentkit/react/lifecycle.spec.tsx +8 -2
- package/src/app/agentkit/react/message-actions.spec.tsx +161 -5
- package/src/app/agentkit/react/saved-reply-reload.spec.tsx +206 -0
- package/src/app/agentkit/react/styles.css +93 -65
- package/src/app/agentkit/react/voice-transcripts.spec.tsx +239 -4
- package/src/app/agentkit/react/voice-transcripts.ts +245 -8
- package/src/app/chat/AgentKitAssistantChat.spec.tsx +59 -11
- package/src/app/chat/AgentKitAssistantChat.tsx +74 -62
- package/src/app/chat/agentkit-chat/guided-answers-context.spec.ts +9 -0
- package/src/app/chat/agentkit-chat/guided-questions.tsx +17 -7
- package/src/app/chat/agentkit-chat/index.ts +1 -0
- package/src/app/chat/chat/run-recovery.spec.tsx +45 -0
- package/src/app/chat/chat/run-recovery.tsx +6 -1
- package/src/app/chat/composer/runtime-adapters.tsx +2 -0
- package/src/app/chat/reply-connection-suggestion.spec.ts +121 -0
- package/src/app/chat/reply-connection-suggestion.ts +76 -0
- package/src/app/i18n/catalogs/ar-SA.ts +10 -0
- package/src/app/i18n/catalogs/de-DE.ts +10 -0
- package/src/app/i18n/catalogs/en-US.ts +10 -0
- package/src/app/i18n/catalogs/es-ES.ts +10 -0
- package/src/app/i18n/catalogs/fr-FR.ts +10 -0
- package/src/app/i18n/catalogs/hi-IN.ts +10 -0
- package/src/app/i18n/catalogs/ja-JP.ts +10 -0
- package/src/app/i18n/catalogs/ko-KR.ts +10 -0
- package/src/app/i18n/catalogs/pt-BR.ts +10 -0
- package/src/app/i18n/catalogs/zh-CN.ts +10 -0
- package/src/app/i18n/catalogs/zh-TW.ts +10 -0
- package/src/app/mcp-approval/McpApprovalReview.spec.tsx +687 -0
- package/src/app/mcp-approval/McpApprovalReview.tsx +913 -0
- package/src/app/onboarding/FirstRunOnboarding.spec.tsx +736 -26
- package/src/app/onboarding/FirstRunOnboarding.tsx +473 -145
- package/src/app/onboarding/GettingStartedCard.tsx +1 -1
- package/src/app/onboarding/first-run-builder-credits-flag.spec.ts +13 -0
- package/src/app/onboarding/first-run-builder-credits-flag.ts +9 -0
- package/src/app/providers/AppProviders.spec.tsx +109 -0
- package/src/app/providers/AppProviders.tsx +53 -1
- package/src/app/resources/McpConnectionSuggestion.spec.ts +77 -12
- package/src/app/resources/McpConnectionSuggestion.tsx +69 -51
- package/src/app/settings/VoiceChatSettings.spec.tsx +6 -1
- package/src/app/settings/account/PreferencesSettings.spec.tsx +73 -0
- package/src/app/settings/account/PreferencesSettings.tsx +24 -7
- package/src/app/settings/account/ThemeFamilySettings.tsx +2 -2
- package/src/app/settings/account/search-entries.spec.ts +14 -0
- package/src/app/settings/account/search-entries.ts +9 -0
- package/src/app/settings/shell/SettingsShell.tsx +29 -2
- package/src/app/shared/AppShellSkeleton.spec.tsx +2 -2
- package/src/app/shared/AppShellSkeleton.tsx +3 -16
- package/src/app/shared/EnvironmentBadge.tsx +3 -4
- package/src/app/shared/is-builder-io-employee.ts +17 -0
- package/src/app/styles/agent-conversation.css +30 -17
- package/src/app/styles/theme-families.css +22 -5
- package/src/app/styles/theme-families.spec.ts +73 -0
- package/src/app/styles/tokens/agent-kit.css +3 -3
- package/src/composer/AgentSuggestionBar.overflow.spec.tsx +1 -1
- package/src/composer/AttachmentChip.spec.tsx +87 -0
- package/src/composer/PromptComposer.context.spec.tsx +8 -4
- package/src/composer/PromptComposer.setup-card.spec.tsx +170 -0
- package/src/composer/PromptComposer.tsx +125 -14
- package/src/composer/RealtimeVoiceMode.spec.tsx +48 -0
- package/src/composer/RealtimeVoiceMode.tsx +45 -2
- package/src/composer/TiptapComposer.tsx +25 -0
- package/src/composer/TiptapComposer.voice-toolbar.spec.tsx +4 -1
- package/src/composer/VoiceButton.tsx +8 -3
- package/src/composer/index.ts +4 -0
- package/src/composer/prompt-attachments.spec.ts +160 -8
- package/src/composer/prompt-attachments.ts +221 -12
- package/src/composer/realtime-voice-transcript.spec.ts +36 -0
- package/src/composer/realtime-voice-transcript.ts +56 -1
- package/src/composer/realtime-voice-turn-metrics.spec.ts +175 -0
- package/src/composer/realtime-voice-turn-metrics.ts +192 -0
- package/src/composer/runtime-adapters.tsx +5 -1
- package/src/composer/useRealtimeVoiceMode.session.spec.tsx +487 -2
- package/src/composer/useRealtimeVoiceMode.spec.ts +267 -65
- package/src/composer/useRealtimeVoiceMode.tsx +716 -139
- package/src/composer/voice-chat-icon.tsx +19 -0
- package/src/editor/DragHandle.spec.ts +217 -0
- package/src/editor/DragHandle.ts +214 -55
- package/src/editor/RegistryBlockNode.spec.ts +172 -2
- package/src/editor/RegistryBlockNode.tsx +91 -13
- package/src/editor/index.ts +4 -0
- package/src/styles.css +2 -0
- package/src/ui/dropdown-menu.tsx +4 -0
|
@@ -5,21 +5,24 @@ import { listFirstRunOnboardingExtensions, } from "@agent-native/core/client/onb
|
|
|
5
5
|
import { saveFirstRunOnboardingRole } from "@agent-native/core/client/onboarding/first-run-status";
|
|
6
6
|
import { createOnboardingCorrelationId, setCustomKeyOnboardingAttempt, setOnboardingExperiment, trackOnboardingEvent, useOnboarding, } from "@agent-native/core/client/onboarding/use-onboarding";
|
|
7
7
|
import { ONBOARDING_PREVIEW_QUERY_PARAM, ONBOARDING_PREVIEW_STEP_QUERY_PARAM, useOnboardingPreviewMode, useOnboardingPreviewStep, } from "@agent-native/core/client/onboarding/use-preview-mode";
|
|
8
|
+
import { useActionMutation } from "@agent-native/core/client/use-action";
|
|
8
9
|
import { SETTINGS_REDESIGN_FLAG } from "@agent-native/core/feature-flags/registry";
|
|
9
10
|
import { buildSettingsRoute, SETTINGS_PAGE_IDS, } from "@agent-native/core/navigation";
|
|
11
|
+
import { FIRST_RUN_BUILDER_CREDITS_V2_EXPERIMENT_ID, FIRST_RUN_BUILDER_CREDITS_V2_FLAG_KEY, } from "@agent-native/core/shared";
|
|
10
12
|
import { Badge } from "@agent-native/toolkit/ui/badge";
|
|
11
13
|
import { Button } from "@agent-native/toolkit/ui/button";
|
|
12
14
|
import { Popover, PopoverContent, PopoverTrigger, } from "@agent-native/toolkit/ui/popover";
|
|
13
15
|
import { Skeleton } from "@agent-native/toolkit/ui/skeleton";
|
|
14
16
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@agent-native/toolkit/ui/tooltip";
|
|
15
17
|
import { cn } from "@agent-native/toolkit/utils";
|
|
16
|
-
import { IconArrowRight, IconChevronDown, IconChevronUp, IconHelpCircle, IconKey, IconLoader2, } from "@tabler/icons-react";
|
|
18
|
+
import { IconAlertCircle, IconArrowRight, IconChevronDown, IconChevronUp, IconHelpCircle, IconKey, IconLoader2, } from "@tabler/icons-react";
|
|
17
19
|
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
18
20
|
import { useNavigate } from "react-router";
|
|
19
21
|
import { useBuilderConnectFlow } from "../settings/useBuilderStatus.js";
|
|
20
22
|
import { BuilderIncludedServices, CapabilityInfoButton, getBuilderIncludedCapabilities, } from "./BuilderIncludedServices.js";
|
|
21
23
|
import { assignFirstRunSetupVariant, FIRST_RUN_SETUP_EXPERIMENT_ID, getPreviewFirstRunSetupVariant, } from "./first-run-experiment.js";
|
|
22
24
|
import { ONBOARDING_PRIMARY_BUTTON_CLASS, OnboardingStepLayout, } from "./OnboardingStepLayout.js";
|
|
25
|
+
const FIRST_RUN_CREDITS_V2_APP_IDS = new Set(["clips", "design", "slides"]);
|
|
23
26
|
function trackFirstRunSetupOutcome(attempt, outcome, errorType) {
|
|
24
27
|
if (!attempt || attempt.outcomeTracked)
|
|
25
28
|
return;
|
|
@@ -33,7 +36,7 @@ function trackFirstRunSetupOutcome(attempt, outcome, errorType) {
|
|
|
33
36
|
...(errorType ? { error_type: errorType } : {}),
|
|
34
37
|
});
|
|
35
38
|
}
|
|
36
|
-
function firstRunStepProperties(screen, beforeSetupExtensions, afterSetupExtensions, extensionPlacement, extensionIndex, extensionStepIndex, setupSkippable) {
|
|
39
|
+
function firstRunStepProperties(screen, beforeSetupExtensions, afterSetupExtensions, extensionPlacement, extensionIndex, extensionStepIndex, setupSkippable, setupRecoverySkippable = false) {
|
|
37
40
|
// `optional` must match whether the screen offers a skip: Analytics funnels
|
|
38
41
|
// read it to keep a skip from counting as drop-off.
|
|
39
42
|
const beforeStepCount = beforeSetupExtensions.reduce((count, extension) => count + (extension.stepCount ?? 1), 0);
|
|
@@ -65,7 +68,9 @@ function firstRunStepProperties(screen, beforeSetupExtensions, afterSetupExtensi
|
|
|
65
68
|
flow: "first_run",
|
|
66
69
|
step_id: screen,
|
|
67
70
|
step_index: stepIndex,
|
|
68
|
-
optional: screen === "role" ||
|
|
71
|
+
optional: screen === "role" ||
|
|
72
|
+
(screen === "choice" && setupSkippable) ||
|
|
73
|
+
(screen === "connecting" && setupRecoverySkippable),
|
|
69
74
|
};
|
|
70
75
|
}
|
|
71
76
|
const SETUP_EXPERIMENT_DECISION_TIMEOUT_MS = 4000;
|
|
@@ -104,12 +109,49 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
104
109
|
const canTrackOnboardingScreen = (!loading && profile !== null) || canRenderRoleWithoutProfile;
|
|
105
110
|
const setupSkippable = profile?.appId === "clips";
|
|
106
111
|
const [setupExperimentDecision, setSetupExperimentDecision] = useState(null);
|
|
107
|
-
const
|
|
108
|
-
|
|
112
|
+
const [creditsV2Assignment, setCreditsV2Assignment] = useState(null);
|
|
113
|
+
const [creditsV2ExposureTracked, setCreditsV2ExposureTracked] = useState(false);
|
|
114
|
+
const creditsV2Flag = useFeatureFlagState(FIRST_RUN_BUILDER_CREDITS_V2_FLAG_KEY);
|
|
115
|
+
const creditsV2FlagAppliesToApp = FIRST_RUN_CREDITS_V2_APP_IDS.has(profile?.appId ?? "");
|
|
116
|
+
const creditsV2Exposure = useActionMutation("record-first-run-builder-credits-v2-exposure", {
|
|
117
|
+
uiOnly: true,
|
|
118
|
+
skipActionQueryInvalidation: true,
|
|
119
|
+
});
|
|
120
|
+
const previewCreditsV2 = previewMode &&
|
|
121
|
+
typeof window !== "undefined" &&
|
|
122
|
+
new URLSearchParams(window.location.search).get("experiment") === "v2";
|
|
123
|
+
const creditsV2Enabled = creditsV2FlagAppliesToApp &&
|
|
124
|
+
creditsV2Flag.status === "ready" &&
|
|
125
|
+
creditsV2Flag.enabled;
|
|
126
|
+
const creditsV2FlowEnabled = creditsV2Enabled || previewCreditsV2;
|
|
127
|
+
const creditsV2FlagPending = !previewMode &&
|
|
128
|
+
creditsV2FlagAppliesToApp &&
|
|
129
|
+
creditsV2Flag.status === "loading";
|
|
130
|
+
const setupVariant = useMemo(() => {
|
|
131
|
+
const previewVariant = previewMode && getPreviewFirstRunSetupVariant(window.location.search);
|
|
132
|
+
if (previewCreditsV2)
|
|
133
|
+
return previewVariant;
|
|
134
|
+
if (previewVariant)
|
|
135
|
+
return previewVariant;
|
|
136
|
+
if (creditsV2FlowEnabled) {
|
|
137
|
+
return creditsV2Assignment?.experiment_variant ?? null;
|
|
138
|
+
}
|
|
139
|
+
return assignFirstRunSetupVariant();
|
|
140
|
+
}, [
|
|
141
|
+
creditsV2FlowEnabled,
|
|
142
|
+
creditsV2Assignment,
|
|
143
|
+
previewCreditsV2,
|
|
144
|
+
previewMode,
|
|
145
|
+
profile?.appId,
|
|
146
|
+
]);
|
|
147
|
+
const setupExperimentId = creditsV2FlowEnabled
|
|
148
|
+
? FIRST_RUN_BUILDER_CREDITS_V2_EXPERIMENT_ID
|
|
149
|
+
: FIRST_RUN_SETUP_EXPERIMENT_ID;
|
|
109
150
|
// The credits arm offers Skip in every app, so analytics must mark the choice step optional there too.
|
|
110
151
|
const choiceSkippable = setupSkippable ||
|
|
111
152
|
(setupVariant === "credits" &&
|
|
112
|
-
(previewMode || setupExperimentDecision === true)
|
|
153
|
+
(previewMode || setupExperimentDecision === true) &&
|
|
154
|
+
(!creditsV2Enabled || creditsV2ExposureTracked));
|
|
113
155
|
const [extensionPlacement, setExtensionPlacement] = useState("after-setup");
|
|
114
156
|
const [extensionIndex, setExtensionIndex] = useState(0);
|
|
115
157
|
const [extensionStepIndex, setExtensionStepIndex] = useState(0);
|
|
@@ -155,11 +197,14 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
155
197
|
previewMode,
|
|
156
198
|
choiceSkippable,
|
|
157
199
|
]);
|
|
158
|
-
const trackFirstRunStepSkipped = useCallback((stepScreen, reason = "user_action", stepExtensionIndex = extensionIndex, stepIndex = extensionStepIndex) => {
|
|
200
|
+
const trackFirstRunStepSkipped = useCallback((stepScreen, reason = "user_action", stepExtensionIndex = extensionIndex, stepIndex = extensionStepIndex, optionalOverride) => {
|
|
159
201
|
if (previewMode)
|
|
160
202
|
return;
|
|
161
203
|
trackOnboardingEvent("onboarding_step_skipped", {
|
|
162
204
|
...firstRunStepProperties(stepScreen, beforeSetupExtensions, afterSetupExtensions, extensionPlacement, stepExtensionIndex, stepIndex, choiceSkippable),
|
|
205
|
+
...(optionalOverride !== undefined
|
|
206
|
+
? { optional: optionalOverride }
|
|
207
|
+
: {}),
|
|
163
208
|
reason,
|
|
164
209
|
});
|
|
165
210
|
}, [
|
|
@@ -175,6 +220,12 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
175
220
|
const completionInFlightRef = useRef(false);
|
|
176
221
|
const completionRedirectRef = useRef(null);
|
|
177
222
|
const setupSkipStartedRef = useRef(false);
|
|
223
|
+
const creditsV2ExposureStartedRef = useRef(false);
|
|
224
|
+
const creditsV2ExposureFailedRef = useRef(false);
|
|
225
|
+
const creditsV2ExposureSettledRef = useRef(false);
|
|
226
|
+
const creditsV2ExposureTrackedRef = useRef(false);
|
|
227
|
+
const creditsV2ExposureConfirmationStartedRef = useRef(false);
|
|
228
|
+
const setupExperimentTimedOutRef = useRef(false);
|
|
178
229
|
const onboardingTerminalRef = useRef(false);
|
|
179
230
|
const abandonmentTrackedRef = useRef(false);
|
|
180
231
|
const onboardingStartedRef = useRef(false);
|
|
@@ -238,13 +289,133 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
238
289
|
trackOnboardingEvent("onboarding_started", { flow: "first_run" });
|
|
239
290
|
}
|
|
240
291
|
}, [canTrackOnboardingScreen, firstRun, previewMode]);
|
|
241
|
-
//
|
|
242
|
-
// credits arm's skip depends on it, so the choice view waits for the decision
|
|
243
|
-
// and is sent once with its resolved optional flag. Without an assigned arm
|
|
244
|
-
// no decision is ever made, and the choice UI renders as is.
|
|
292
|
+
// The v2 choice event waits until the rendered arm has been attributed.
|
|
245
293
|
const choiceStepKnown = screen !== "choice" ||
|
|
246
|
-
|
|
247
|
-
|
|
294
|
+
(!creditsV2FlagPending &&
|
|
295
|
+
(!creditsV2FlowEnabled || setupExperimentDecision !== null) &&
|
|
296
|
+
(setupVariant === null || setupExperimentDecision !== null) &&
|
|
297
|
+
(!creditsV2Enabled ||
|
|
298
|
+
setupExperimentDecision !== true ||
|
|
299
|
+
creditsV2ExposureTracked));
|
|
300
|
+
const beginBeforeSetup = useCallback(() => {
|
|
301
|
+
if (beforeSetupExtensions.length === 0) {
|
|
302
|
+
setScreen("choice");
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
setExtensionPlacement("before-setup");
|
|
306
|
+
setExtensionIndex(0);
|
|
307
|
+
setExtensionStepIndex(0);
|
|
308
|
+
setScreen("extension");
|
|
309
|
+
}, [beforeSetupExtensions.length]);
|
|
310
|
+
const handleFinish = useCallback((completedScreen, track = true) => {
|
|
311
|
+
if (afterSetupExtensions.length === 0) {
|
|
312
|
+
void finishOnboarding(completedScreen);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
if (completedScreen && track)
|
|
316
|
+
trackFirstRunStepCompleted(completedScreen);
|
|
317
|
+
setExtensionPlacement("after-setup");
|
|
318
|
+
setExtensionIndex(0);
|
|
319
|
+
setExtensionStepIndex(0);
|
|
320
|
+
setScreen("extension");
|
|
321
|
+
}, [afterSetupExtensions.length, finishOnboarding, trackFirstRunStepCompleted]);
|
|
322
|
+
const skipFailedBuilderSetup = useCallback(() => {
|
|
323
|
+
if (setupSkipStartedRef.current || completionInFlightRef.current)
|
|
324
|
+
return;
|
|
325
|
+
setupSkipStartedRef.current = true;
|
|
326
|
+
trackFirstRunStepSkipped("connecting", "builder_provision_failed", extensionIndex, extensionStepIndex, true);
|
|
327
|
+
if (setupSkippable)
|
|
328
|
+
completionRedirectRef.current = "/record";
|
|
329
|
+
handleFinish(null);
|
|
330
|
+
}, [
|
|
331
|
+
extensionIndex,
|
|
332
|
+
extensionStepIndex,
|
|
333
|
+
handleFinish,
|
|
334
|
+
setupSkippable,
|
|
335
|
+
trackFirstRunStepSkipped,
|
|
336
|
+
]);
|
|
337
|
+
const handleBuilderConnected = useCallback(() => {
|
|
338
|
+
trackFirstRunSetupOutcome(builderSetupAttemptRef.current, "connected");
|
|
339
|
+
builderSetupAttemptRef.current = null;
|
|
340
|
+
setupAttemptRef.current = null;
|
|
341
|
+
trackFirstRunStepCompleted("choice");
|
|
342
|
+
trackFirstRunStepCompleted("connecting");
|
|
343
|
+
handleFinish(null);
|
|
344
|
+
}, [handleFinish, trackFirstRunStepCompleted]);
|
|
345
|
+
const connectFlow = useBuilderConnectFlow({
|
|
346
|
+
enabled: firstRun && !previewMode,
|
|
347
|
+
provisionAccount: true,
|
|
348
|
+
trackingSource: "first_run_onboarding",
|
|
349
|
+
trackingFlow: "connect_llm",
|
|
350
|
+
onConnected: handleBuilderConnected,
|
|
351
|
+
});
|
|
352
|
+
const accountExists = connectFlow.accountExists && !connectFlow.connecting;
|
|
353
|
+
const provisioning = builderConnectionMode === "provision" && !accountExists;
|
|
354
|
+
const provisioningFailed = provisioning &&
|
|
355
|
+
!connectFlow.connecting &&
|
|
356
|
+
Boolean(connectFlow.terminalError);
|
|
357
|
+
const connectionFailed = provisioningFailed;
|
|
358
|
+
useEffect(() => {
|
|
359
|
+
if (previewMode ||
|
|
360
|
+
!firstRun ||
|
|
361
|
+
!canTrackOnboardingScreen ||
|
|
362
|
+
screen !== "choice" ||
|
|
363
|
+
!creditsV2Enabled ||
|
|
364
|
+
setupExperimentDecision !== true ||
|
|
365
|
+
creditsV2ExposureTrackedRef.current ||
|
|
366
|
+
!creditsV2Assignment) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
creditsV2ExposureTrackedRef.current = true;
|
|
370
|
+
setOnboardingExperiment({
|
|
371
|
+
id: creditsV2Assignment.experiment_id,
|
|
372
|
+
variant: creditsV2Assignment.experiment_variant,
|
|
373
|
+
});
|
|
374
|
+
setCreditsV2ExposureTracked(true);
|
|
375
|
+
trackOnboardingEvent("onboarding_experiment_exposed", {
|
|
376
|
+
flow: "first_run",
|
|
377
|
+
step_id: "choice",
|
|
378
|
+
experiment_id: creditsV2Assignment.experiment_id,
|
|
379
|
+
experiment_variant: creditsV2Assignment.experiment_variant,
|
|
380
|
+
});
|
|
381
|
+
if (creditsV2ExposureConfirmationStartedRef.current)
|
|
382
|
+
return;
|
|
383
|
+
creditsV2ExposureConfirmationStartedRef.current = true;
|
|
384
|
+
const persistExposure = async () => {
|
|
385
|
+
let lastError;
|
|
386
|
+
// A write can commit even when its response is lost, so retry the idempotent assignment to reconcile it.
|
|
387
|
+
for (const delayMs of [0, 0, 1_000, 5_000, 30_000]) {
|
|
388
|
+
if (delayMs > 0) {
|
|
389
|
+
await new Promise((resolve) => window.setTimeout(resolve, delayMs));
|
|
390
|
+
}
|
|
391
|
+
try {
|
|
392
|
+
const { assignment } = await creditsV2Exposure.mutateAsync({
|
|
393
|
+
confirmedVariant: creditsV2Assignment.experiment_variant,
|
|
394
|
+
});
|
|
395
|
+
if (assignment?.experiment_id !== creditsV2Assignment.experiment_id ||
|
|
396
|
+
assignment.experiment_variant !==
|
|
397
|
+
creditsV2Assignment.experiment_variant) {
|
|
398
|
+
throw new Error("The server did not persist the displayed first-run Builder credits v2 assignment.");
|
|
399
|
+
}
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
lastError = error;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
console.error("Failed to persist first-run Builder credits v2 exposure:", lastError);
|
|
407
|
+
};
|
|
408
|
+
void persistExposure();
|
|
409
|
+
}, [
|
|
410
|
+
canTrackOnboardingScreen,
|
|
411
|
+
creditsV2Assignment,
|
|
412
|
+
creditsV2Enabled,
|
|
413
|
+
creditsV2Exposure.mutateAsync,
|
|
414
|
+
firstRun,
|
|
415
|
+
previewMode,
|
|
416
|
+
setupExperimentDecision,
|
|
417
|
+
screen,
|
|
418
|
+
]);
|
|
248
419
|
useEffect(() => {
|
|
249
420
|
if (previewMode ||
|
|
250
421
|
!firstRun ||
|
|
@@ -253,8 +424,13 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
253
424
|
stepViewRef.current = null;
|
|
254
425
|
return;
|
|
255
426
|
}
|
|
256
|
-
const step = firstRunStepProperties(screen, beforeSetupExtensions, afterSetupExtensions, extensionPlacement, extensionIndex, extensionStepIndex, choiceSkippable);
|
|
257
|
-
const key = [
|
|
427
|
+
const step = firstRunStepProperties(screen, beforeSetupExtensions, afterSetupExtensions, extensionPlacement, extensionIndex, extensionStepIndex, choiceSkippable, provisioningFailed);
|
|
428
|
+
const key = [
|
|
429
|
+
step.step_id,
|
|
430
|
+
step.extension_id,
|
|
431
|
+
step.step_index,
|
|
432
|
+
step.optional,
|
|
433
|
+
].join(":");
|
|
258
434
|
if (stepViewRef.current?.key !== key) {
|
|
259
435
|
stepViewRef.current = { key, id: createOnboardingCorrelationId() };
|
|
260
436
|
}
|
|
@@ -275,6 +451,7 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
275
451
|
previewMode,
|
|
276
452
|
canTrackOnboardingScreen,
|
|
277
453
|
choiceStepKnown,
|
|
454
|
+
provisioningFailed,
|
|
278
455
|
screen,
|
|
279
456
|
]);
|
|
280
457
|
useEffect(() => {
|
|
@@ -289,7 +466,7 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
289
466
|
return;
|
|
290
467
|
abandonmentTrackedRef.current = true;
|
|
291
468
|
trackOnboardingEvent("onboarding_abandoned", {
|
|
292
|
-
...firstRunStepProperties(screen, beforeSetupExtensions, afterSetupExtensions, extensionPlacement, extensionIndex, extensionStepIndex, choiceSkippable),
|
|
469
|
+
...firstRunStepProperties(screen, beforeSetupExtensions, afterSetupExtensions, extensionPlacement, extensionIndex, extensionStepIndex, choiceSkippable, provisioningFailed),
|
|
293
470
|
reason: "page_exit",
|
|
294
471
|
});
|
|
295
472
|
};
|
|
@@ -306,44 +483,8 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
306
483
|
canTrackOnboardingScreen,
|
|
307
484
|
screen,
|
|
308
485
|
choiceSkippable,
|
|
486
|
+
provisioningFailed,
|
|
309
487
|
]);
|
|
310
|
-
const beginBeforeSetup = useCallback(() => {
|
|
311
|
-
if (beforeSetupExtensions.length === 0) {
|
|
312
|
-
setScreen("choice");
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
setExtensionPlacement("before-setup");
|
|
316
|
-
setExtensionIndex(0);
|
|
317
|
-
setExtensionStepIndex(0);
|
|
318
|
-
setScreen("extension");
|
|
319
|
-
}, [beforeSetupExtensions.length]);
|
|
320
|
-
const handleFinish = useCallback((completedScreen, track = true) => {
|
|
321
|
-
if (afterSetupExtensions.length === 0) {
|
|
322
|
-
void finishOnboarding(completedScreen);
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
if (completedScreen && track)
|
|
326
|
-
trackFirstRunStepCompleted(completedScreen);
|
|
327
|
-
setExtensionPlacement("after-setup");
|
|
328
|
-
setExtensionIndex(0);
|
|
329
|
-
setExtensionStepIndex(0);
|
|
330
|
-
setScreen("extension");
|
|
331
|
-
}, [afterSetupExtensions.length, finishOnboarding, trackFirstRunStepCompleted]);
|
|
332
|
-
const handleBuilderConnected = useCallback(() => {
|
|
333
|
-
trackFirstRunSetupOutcome(builderSetupAttemptRef.current, "connected");
|
|
334
|
-
builderSetupAttemptRef.current = null;
|
|
335
|
-
setupAttemptRef.current = null;
|
|
336
|
-
trackFirstRunStepCompleted("choice");
|
|
337
|
-
trackFirstRunStepCompleted("connecting");
|
|
338
|
-
handleFinish(null);
|
|
339
|
-
}, [handleFinish, trackFirstRunStepCompleted]);
|
|
340
|
-
const connectFlow = useBuilderConnectFlow({
|
|
341
|
-
enabled: firstRun && !previewMode,
|
|
342
|
-
provisionAccount: true,
|
|
343
|
-
trackingSource: "first_run_onboarding",
|
|
344
|
-
trackingFlow: "connect_llm",
|
|
345
|
-
onConnected: handleBuilderConnected,
|
|
346
|
-
});
|
|
347
488
|
const builderStatusReadCount = connectFlow.statusReadSettledCount ?? 0;
|
|
348
489
|
useEffect(() => {
|
|
349
490
|
const startedAt = retryingBuilderStatusAtCountRef.current;
|
|
@@ -368,12 +509,13 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
368
509
|
trackFirstRunSetupOutcome(attempt, "failed", "account_exists");
|
|
369
510
|
return;
|
|
370
511
|
}
|
|
371
|
-
if (connectFlow.terminalError) {
|
|
512
|
+
if (connectFlow.terminalError || connectFlow.statusUnavailable) {
|
|
372
513
|
trackFirstRunSetupOutcome(attempt, "failed", "connection_error");
|
|
373
514
|
}
|
|
374
515
|
}, [
|
|
375
516
|
connectFlow.accountExists,
|
|
376
517
|
connectFlow.connecting,
|
|
518
|
+
connectFlow.statusUnavailable,
|
|
377
519
|
connectFlow.terminalError,
|
|
378
520
|
]);
|
|
379
521
|
// Preview never fetches status, so show the activation path it would offer.
|
|
@@ -386,11 +528,14 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
386
528
|
// page in both arms and stays out of the results.
|
|
387
529
|
const setupExperimentEligible = setupStatusSettled &&
|
|
388
530
|
canActivateBuilderFreeCredits &&
|
|
389
|
-
!connectFlow.configured
|
|
531
|
+
!connectFlow.configured &&
|
|
532
|
+
!connectFlow.statusUnavailable;
|
|
390
533
|
useEffect(() => {
|
|
391
534
|
if (previewMode ||
|
|
392
535
|
!firstRun ||
|
|
393
536
|
screen !== "choice" ||
|
|
537
|
+
creditsV2FlagPending ||
|
|
538
|
+
creditsV2FlowEnabled ||
|
|
394
539
|
!setupVariant ||
|
|
395
540
|
!setupStatusSettled ||
|
|
396
541
|
setupExperimentDecision !== null) {
|
|
@@ -398,12 +543,14 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
398
543
|
}
|
|
399
544
|
if (setupExperimentEligible) {
|
|
400
545
|
setOnboardingExperiment({
|
|
401
|
-
id:
|
|
546
|
+
id: setupExperimentId,
|
|
402
547
|
variant: setupVariant,
|
|
403
548
|
});
|
|
404
549
|
trackOnboardingEvent("onboarding_experiment_exposed", {
|
|
405
550
|
flow: "first_run",
|
|
406
551
|
step_id: "choice",
|
|
552
|
+
experiment_id: setupExperimentId,
|
|
553
|
+
experiment_variant: setupVariant,
|
|
407
554
|
});
|
|
408
555
|
}
|
|
409
556
|
setSetupExperimentDecision(setupExperimentEligible);
|
|
@@ -411,11 +558,73 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
411
558
|
firstRun,
|
|
412
559
|
previewMode,
|
|
413
560
|
screen,
|
|
561
|
+
creditsV2FlagPending,
|
|
562
|
+
creditsV2FlowEnabled,
|
|
414
563
|
setupExperimentEligible,
|
|
415
564
|
setupExperimentDecision,
|
|
416
565
|
setupStatusSettled,
|
|
566
|
+
setupExperimentId,
|
|
417
567
|
setupVariant,
|
|
418
568
|
]);
|
|
569
|
+
useEffect(() => {
|
|
570
|
+
if (previewMode ||
|
|
571
|
+
!firstRun ||
|
|
572
|
+
screen !== "choice" ||
|
|
573
|
+
!creditsV2Enabled ||
|
|
574
|
+
!setupStatusSettled ||
|
|
575
|
+
setupExperimentTimedOutRef.current ||
|
|
576
|
+
setupExperimentDecision === true) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (!setupExperimentEligible) {
|
|
580
|
+
creditsV2ExposureFailedRef.current = false;
|
|
581
|
+
setSetupExperimentDecision(false);
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
if (creditsV2ExposureFailedRef.current)
|
|
585
|
+
return;
|
|
586
|
+
if (creditsV2ExposureStartedRef.current)
|
|
587
|
+
return;
|
|
588
|
+
creditsV2ExposureStartedRef.current = true;
|
|
589
|
+
creditsV2ExposureSettledRef.current = false;
|
|
590
|
+
setSetupExperimentDecision(null);
|
|
591
|
+
void creditsV2Exposure
|
|
592
|
+
.mutateAsync({})
|
|
593
|
+
.then(({ assignment }) => {
|
|
594
|
+
creditsV2ExposureSettledRef.current = true;
|
|
595
|
+
if (setupExperimentTimedOutRef.current)
|
|
596
|
+
return;
|
|
597
|
+
if (assignment?.experiment_id !==
|
|
598
|
+
FIRST_RUN_BUILDER_CREDITS_V2_EXPERIMENT_ID ||
|
|
599
|
+
(assignment.experiment_variant !== "control" &&
|
|
600
|
+
assignment.experiment_variant !== "credits")) {
|
|
601
|
+
setSetupExperimentDecision(false);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
setCreditsV2Assignment({
|
|
605
|
+
experiment_id: FIRST_RUN_BUILDER_CREDITS_V2_EXPERIMENT_ID,
|
|
606
|
+
experiment_variant: assignment.experiment_variant,
|
|
607
|
+
});
|
|
608
|
+
setSetupExperimentDecision(true);
|
|
609
|
+
})
|
|
610
|
+
.catch(() => {
|
|
611
|
+
creditsV2ExposureSettledRef.current = true;
|
|
612
|
+
if (setupExperimentTimedOutRef.current)
|
|
613
|
+
return;
|
|
614
|
+
creditsV2ExposureStartedRef.current = false;
|
|
615
|
+
creditsV2ExposureFailedRef.current = true;
|
|
616
|
+
setSetupExperimentDecision(false);
|
|
617
|
+
});
|
|
618
|
+
}, [
|
|
619
|
+
creditsV2Enabled,
|
|
620
|
+
creditsV2Exposure.mutateAsync,
|
|
621
|
+
firstRun,
|
|
622
|
+
previewMode,
|
|
623
|
+
screen,
|
|
624
|
+
setupExperimentDecision,
|
|
625
|
+
setupExperimentEligible,
|
|
626
|
+
setupStatusSettled,
|
|
627
|
+
]);
|
|
419
628
|
// A stalled Builder status read must not leave the setup screen blank. Past
|
|
420
629
|
// the limit the person gets the existing page and stays out of the
|
|
421
630
|
// experiment, identically in both arms, so exposure counts stay honest.
|
|
@@ -423,13 +632,28 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
423
632
|
if (previewMode ||
|
|
424
633
|
!firstRun ||
|
|
425
634
|
screen !== "choice" ||
|
|
426
|
-
|
|
635
|
+
creditsV2FlagPending ||
|
|
636
|
+
(!setupVariant && !creditsV2FlowEnabled) ||
|
|
427
637
|
setupExperimentDecision !== null) {
|
|
428
638
|
return;
|
|
429
639
|
}
|
|
430
|
-
const timer = window.setTimeout(() =>
|
|
640
|
+
const timer = window.setTimeout(() => {
|
|
641
|
+
if (creditsV2ExposureSettledRef.current)
|
|
642
|
+
return;
|
|
643
|
+
setupExperimentTimedOutRef.current = true;
|
|
644
|
+
setSetupExperimentDecision((decision) => decision ?? false);
|
|
645
|
+
}, SETUP_EXPERIMENT_DECISION_TIMEOUT_MS);
|
|
431
646
|
return () => window.clearTimeout(timer);
|
|
432
|
-
}, [
|
|
647
|
+
}, [
|
|
648
|
+
creditsV2FlowEnabled,
|
|
649
|
+
creditsV2FlagPending,
|
|
650
|
+
firstRun,
|
|
651
|
+
previewMode,
|
|
652
|
+
screen,
|
|
653
|
+
setupExperimentDecision,
|
|
654
|
+
setupStatusSettled,
|
|
655
|
+
setupVariant,
|
|
656
|
+
]);
|
|
433
657
|
const retryOnboardingCompletion = useCallback(() => {
|
|
434
658
|
const attempt = completionAttemptRef.current;
|
|
435
659
|
void finishOnboarding(attempt?.screen ?? null, attempt?.extensionIndex ?? extensionIndex, attempt?.redirect ?? null);
|
|
@@ -588,9 +812,10 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
588
812
|
// shows, plus the app's own headline capabilities it covers.
|
|
589
813
|
const builderCapabilities = getBuilderIncludedCapabilities(profile.capabilities);
|
|
590
814
|
const inCreditsArm = setupVariant === "credits";
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
815
|
+
if (!previewMode &&
|
|
816
|
+
(creditsV2FlagPending ||
|
|
817
|
+
(creditsV2FlowEnabled && setupExperimentDecision === null) ||
|
|
818
|
+
(setupVariant && setupExperimentDecision === null))) {
|
|
594
819
|
return _jsx(OnboardingSkeleton, {});
|
|
595
820
|
}
|
|
596
821
|
const creditsEligible = inCreditsArm && (previewMode || setupExperimentDecision === true);
|
|
@@ -619,10 +844,10 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
619
844
|
};
|
|
620
845
|
return (_jsx(OnboardingShell, { profile: profile, screen: "choice", progressWidth: progressWidth, ...completionErrorProps, children: _jsxs("div", { "data-testid": "first-run-credits-offer", className: "mx-auto flex w-full flex-col items-center gap-5 pt-[max(0rem,6vh)] text-center", children: [_jsx("h1", { className: cn("text-balance text-[28px] font-bold leading-tight tracking-[-0.02em] text-foreground", profile.appId === "clips" ? "max-w-lg" : "max-w-sm"), children: profile.appId === "clips"
|
|
621
846
|
? t("agentChat.onboarding.creditsTitleClips")
|
|
622
|
-
: t("agentChat.onboarding.creditsTitle") }), _jsxs("p", { className: "max-w-sm text-sm leading-6 text-muted-foreground", children: [t("agentChat.onboarding.creditsSubtitle"), " ", _jsx("button", { type: "button", "data-testid": "first-run-credits-learn-more", "aria-expanded": moreInfoOpen, "aria-controls": moreInfoOpen ? "first-run-credits-details" : undefined, className: "rounded-sm underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: toggleMoreInfo, children: t("agentChat.onboarding.creditsLearnMore") })] }), _jsxs("div", { className: "flex w-full max-w-sm flex-col items-center gap-3", children: [_jsx("button", { type: "button", "data-testid": "first-run-credits-activate", className: cn(ONBOARDING_PRIMARY_BUTTON_CLASS, "min-h-11 w-full text-sm"), onClick: () => handleBuilder(true), disabled: connectFlow.connecting, children: t("agentChat.onboarding.creditsActivate") }), _jsx("button", { type: "button", "data-testid": "first-run-credits-connect-existing", className: cn(mutedButtonClass, "min-h-11 w-full text-sm"), onClick: () => handleBuilder(false), disabled: connectFlow.connecting, children: t("agentChat.onboarding.builderExistingAccount") }), _jsxs("p", { className: "text-xs leading-5 text-muted-foreground", children: [t("agentChat.onboarding.creditsFinePrint"), " ", _jsx("a", { href: "https://www.builder.io/legal/terms", target: "_blank", rel: "noreferrer", className: "underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: t("agentChat.onboarding.builderTerms") }), " ", t("agentChat.onboarding.builderConsentAnd"), " ", _jsx("a", { href: "https://www.builder.io/legal/privacy", target: "_blank", rel: "noreferrer", className: "underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: t("agentChat.onboarding.builderPrivacy") }), "."] })] }), builderStatusError, _jsx("div", { className: "flex flex-wrap items-center justify-center gap-x-3 gap-y-2", children: _jsxs("button", { type: "button", "data-testid": "first-run-credits-more-info", "aria-expanded": moreInfoOpen, "aria-controls": moreInfoOpen ? "first-run-credits-details" : undefined, className: "inline-flex min-h-8 items-center gap-1 rounded-full border border-border px-3 text-xs font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: toggleMoreInfo, children: [t("agentChat.onboarding.creditsMoreInfo"), _jsx(MoreInfoChevron, { size: 14, "aria-hidden": true })] }) }), moreInfoOpen && (_jsx("div", { id: "first-run-credits-details", "data-testid": "first-run-credits-details", className: "mt-3 flex w-full max-w-3xl flex-col gap-6 text-left", children: setupCards })), _jsx("div", { className: "fixed bottom-6 right-6 z-10", children: _jsxs(Popover, { open: skipConfirmOpen, onOpenChange: setSkipConfirmOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-testid": "first-run-credits-skip", className: "inline-flex min-h-6 items-center px-2 rounded-sm text-xs font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: t("agentChat.onboarding.creditsSkip") }) }), _jsxs(PopoverContent, { side: "top", align: "end", portalled: false, "aria-labelledby": "first-run-credits-skip-title", "aria-describedby": "first-run-credits-skip-body", className: "w-96 max-w-[calc(100vw-2rem)] space-y-3 p-4 text-left", onOpenAutoFocus: (event) => {
|
|
847
|
+
: t("agentChat.onboarding.creditsTitle") }), _jsxs("p", { className: "max-w-sm text-sm leading-6 text-muted-foreground", children: [t("agentChat.onboarding.creditsSubtitle"), " ", _jsx("button", { type: "button", "data-testid": "first-run-credits-learn-more", "aria-expanded": moreInfoOpen, "aria-controls": moreInfoOpen ? "first-run-credits-details" : undefined, className: "rounded-sm underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: toggleMoreInfo, children: t("agentChat.onboarding.creditsLearnMore") })] }), _jsxs("div", { className: "flex w-full max-w-sm flex-col items-center gap-3", children: [_jsx("button", { type: "button", "data-testid": "first-run-credits-activate", className: cn(ONBOARDING_PRIMARY_BUTTON_CLASS, "min-h-11 w-full text-sm"), onClick: () => handleBuilder(true), disabled: connectFlow.connecting, children: t("agentChat.onboarding.creditsActivate") }), _jsx("button", { type: "button", "data-testid": "first-run-credits-connect-existing", className: cn(mutedButtonClass, "min-h-11 w-full text-sm"), onClick: () => handleBuilder(false), disabled: connectFlow.connecting, children: t("agentChat.onboarding.builderExistingAccount") }), creditsV2FlowEnabled && (_jsx("button", { type: "button", "data-testid": "first-run-credits-own-api-keys", className: "min-h-7 text-xs font-medium text-muted-foreground underline underline-offset-4 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => void handleOpenSettings(), disabled: connectFlow.connecting, children: t("agentChat.onboarding.creditsUseOwnApiKeys") })), _jsxs("p", { className: "text-xs leading-5 text-muted-foreground", children: [t("agentChat.onboarding.creditsFinePrint"), " ", _jsx("a", { href: "https://www.builder.io/legal/terms", target: "_blank", rel: "noreferrer", className: "underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: t("agentChat.onboarding.builderTerms") }), " ", t("agentChat.onboarding.builderConsentAnd"), " ", _jsx("a", { href: "https://www.builder.io/legal/privacy", target: "_blank", rel: "noreferrer", className: "underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: t("agentChat.onboarding.builderPrivacy") }), "."] })] }), builderStatusError, _jsx("div", { className: "flex flex-wrap items-center justify-center gap-x-3 gap-y-2", children: _jsxs("button", { type: "button", "data-testid": "first-run-credits-more-info", "aria-expanded": moreInfoOpen, "aria-controls": moreInfoOpen ? "first-run-credits-details" : undefined, className: "inline-flex min-h-8 items-center gap-1 rounded-full border border-border px-3 text-xs font-medium text-foreground transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: toggleMoreInfo, children: [t("agentChat.onboarding.creditsMoreInfo"), _jsx(MoreInfoChevron, { size: 14, "aria-hidden": true })] }) }), moreInfoOpen && (_jsx("div", { id: "first-run-credits-details", "data-testid": "first-run-credits-details", className: "mt-3 flex w-full max-w-3xl flex-col gap-6 text-left", children: setupCards })), _jsx("div", { className: "fixed bottom-6 right-6 z-10", children: creditsV2FlowEnabled ? (_jsx("button", { type: "button", "data-testid": "first-run-credits-skip", className: "inline-flex min-h-6 items-center px-2 rounded-sm text-xs font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: skipSetup, children: t("agentChat.onboarding.creditsSkip") })) : (_jsxs(Popover, { open: skipConfirmOpen, onOpenChange: setSkipConfirmOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-testid": "first-run-credits-skip", className: "inline-flex min-h-6 items-center px-2 rounded-sm text-xs font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: t("agentChat.onboarding.creditsSkip") }) }), _jsxs(PopoverContent, { side: "top", align: "end", portalled: false, "aria-labelledby": "first-run-credits-skip-title", "aria-describedby": "first-run-credits-skip-body", className: "w-96 max-w-[calc(100vw-2rem)] space-y-3 p-4 text-left", onOpenAutoFocus: (event) => {
|
|
623
848
|
event.preventDefault();
|
|
624
849
|
skipGoBackRef.current?.focus();
|
|
625
|
-
}, children: [_jsxs("div", { className: "space-y-1", children: [_jsx("p", { id: "first-run-credits-skip-title", className: "text-sm font-semibold text-foreground", children: t("agentChat.onboarding.creditsSkipConfirmTitle") }), _jsx("p", { id: "first-run-credits-skip-body", className: "text-xs leading-5 text-muted-foreground", children: t("agentChat.onboarding.creditsSkipConfirmBody") })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "px-0 text-muted-foreground hover:bg-transparent hover:text-foreground", onClick: () => void handleOpenSettings(), children: t("agentChat.onboarding.creditsUseCustomKeys") }), _jsxs("div", { className: "flex flex-wrap justify-end gap-2", children: [_jsx(Button, { type: "button", variant: "secondary", size: "sm", "data-testid": "first-run-credits-skip-confirm", onClick: skipSetup, children: t("agentChat.onboarding.creditsSkipAnyway") }), _jsx(Button, { type: "button", size: "sm", ref: skipGoBackRef, onClick: () => setSkipConfirmOpen(false), children: t("agentChat.onboarding.creditsSkipGoBack") })] })] })] })] }) })] }) }));
|
|
850
|
+
}, children: [_jsxs("div", { className: "space-y-1", children: [_jsx("p", { id: "first-run-credits-skip-title", className: "text-sm font-semibold text-foreground", children: t("agentChat.onboarding.creditsSkipConfirmTitle") }), _jsx("p", { id: "first-run-credits-skip-body", className: "text-xs leading-5 text-muted-foreground", children: t("agentChat.onboarding.creditsSkipConfirmBody") })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "px-0 text-muted-foreground hover:bg-transparent hover:text-foreground", onClick: () => void handleOpenSettings(), children: t("agentChat.onboarding.creditsUseCustomKeys") }), _jsxs("div", { className: "flex flex-wrap justify-end gap-2", children: [_jsx(Button, { type: "button", variant: "secondary", size: "sm", "data-testid": "first-run-credits-skip-confirm", onClick: skipSetup, children: t("agentChat.onboarding.creditsSkipAnyway") }), _jsx(Button, { type: "button", size: "sm", ref: skipGoBackRef, onClick: () => setSkipConfirmOpen(false), children: t("agentChat.onboarding.creditsSkipGoBack") })] })] })] })] })) })] }) }));
|
|
626
851
|
}
|
|
627
852
|
return (_jsx(OnboardingShell, { profile: profile, screen: "choice", progressWidth: progressWidth, ...completionErrorProps, children: _jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-9", children: [_jsxs("div", { className: "flex flex-col gap-6", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("h1", { className: "text-[28px] font-bold leading-tight tracking-[-0.02em] text-foreground", children: "Choose your setup" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "We recommend starting with Builder.io for the fastest setup." })] }), setupCards, setupSkipButton] }), _jsxs("p", { className: "text-center text-xs leading-5 text-muted-foreground", children: [t("agentChat.onboarding.builderConsentPrefix"), " ", _jsx("a", { href: "https://www.builder.io/legal/terms", target: "_blank", rel: "noreferrer", className: "underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: t("agentChat.onboarding.builderTerms") }), " ", t("agentChat.onboarding.builderConsentAnd"), " ", _jsx("a", { href: "https://www.builder.io/legal/privacy", target: "_blank", rel: "noreferrer", className: "underline underline-offset-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: t("agentChat.onboarding.builderPrivacy") }), "."] })] }) }));
|
|
628
853
|
}
|
|
@@ -645,22 +870,25 @@ export function FirstRunOnboarding({ initialFirstRun = false, } = {}) {
|
|
|
645
870
|
});
|
|
646
871
|
}, className: "size-4 shrink-0 accent-primary" }), _jsx("span", { className: "font-medium text-foreground", children: t(labelKey) })] }, value)))] }), selectedRole === "other" && (_jsxs("div", { className: "mt-4 flex flex-col gap-2", children: [_jsx("label", { htmlFor: "first-run-role-other", className: "text-sm font-medium text-foreground", children: t("agentChat.onboarding.roleOtherInputLabel") }), _jsx("input", { id: "first-run-role-other", "data-testid": "first-run-role-other-input", type: "text", value: customRole, maxLength: 120, disabled: savingRole, onChange: (event) => setCustomRole(event.target.value), className: "min-h-10 rounded-lg border border-border bg-card px-3 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary/40 focus:ring-2 focus:ring-ring" })] })), roleSaveError && (_jsx("p", { className: "mt-4 text-xs leading-5 text-destructive", role: "alert", children: roleSaveError }))] }) }) }));
|
|
647
872
|
}
|
|
648
|
-
const accountExists = connectFlow.accountExists && !connectFlow.connecting;
|
|
649
|
-
const provisioning = builderConnectionMode === "provision" && !accountExists;
|
|
650
873
|
const returnToSetupChoice = () => setScreen("choice");
|
|
651
|
-
return (_jsx(OnboardingShell, { profile: profile, screen: "connecting", progressWidth: progressWidth, ...completionErrorProps, children: _jsxs("div", { className: "mx-auto flex w-full max-w-md flex-col items-center text-center", role: "status", "aria-live": "polite", "aria-busy": connectFlow.connecting, children: [
|
|
874
|
+
return (_jsx(OnboardingShell, { profile: profile, screen: "connecting", progressWidth: progressWidth, ...completionErrorProps, children: _jsxs("div", { className: "mx-auto flex w-full max-w-md flex-col items-center text-center", role: "status", "aria-live": "polite", "aria-busy": connectFlow.connecting, children: [_jsxs("div", { className: cn("flex size-10 items-center justify-center rounded-full", connectionFailed
|
|
875
|
+
? "bg-destructive/10 text-destructive"
|
|
876
|
+
: "bg-primary/10 text-primary"), children: [accountExists ? _jsx(IconKey, { size: 19 }) : null, connectionFailed ? _jsx(IconAlertCircle, { size: 19 }) : null, !accountExists && !connectionFailed ? (_jsx(IconLoader2, { className: "animate-spin", size: 19 })) : null] }), _jsx("h1", { className: "mt-5 text-xl font-semibold tracking-[-0.04em]", children: accountExists
|
|
652
877
|
? t("agentChat.onboarding.builderAccountExistsTitle")
|
|
653
|
-
:
|
|
654
|
-
? t("agentChat.
|
|
655
|
-
:
|
|
878
|
+
: provisioningFailed
|
|
879
|
+
? t("agentChat.settingsShell.builder.setupFailed")
|
|
880
|
+
: provisioning
|
|
881
|
+
? t("agentChat.onboarding.creditsActivating")
|
|
882
|
+
: t("agentChat.onboarding.builderConnecting") }), _jsx("p", { className: "mt-2 text-sm text-muted-foreground", role: connectionFailed ? "alert" : undefined, children: accountExists ? (t("agentChat.onboarding.builderAccountExistsDescription")) : provisioningFailed ? (t("agentChat.onboarding.builderProvisionFailedDetail")) : provisioning ? (_jsxs(_Fragment, { children: [t("agentChat.onboarding.builderProvisioningDescription"), _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": t("agentChat.onboarding.creditsAboutLabel"), className: "ml-0 inline-flex size-6 items-center justify-center rounded-full align-middle text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconHelpCircle, { size: 12, "aria-hidden": true }) }) }), _jsx(TooltipContent, { side: "top", className: "max-w-xs text-xs", children: t("agentChat.onboarding.creditsActivatingTooltip") })] }) })] })) : (t("agentChat.onboarding.builderConnectionDescription")) }), accountExists ? (_jsxs("button", { type: "button", className: cn(ONBOARDING_PRIMARY_BUTTON_CLASS, "mt-7 w-full"), onClick: () => handleBuilder(false), disabled: connectFlow.connecting, children: [t("agentChat.auth.logIn"), _jsx(IconArrowRight, { size: 15 })] })) : (_jsxs(_Fragment, { children: [connectFlow.connecting ? (_jsxs("div", { className: "mt-7 w-full rounded-xl bg-muted/35 p-4 text-left", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Skeleton, { className: "h-3 w-28" }), _jsx(Skeleton, { className: "h-5 w-16 rounded-full" })] }), _jsx(Skeleton, { className: "mt-4 h-8 w-full" }), _jsxs("div", { className: "mt-3 grid grid-cols-3 gap-2", children: [_jsx(Skeleton, { className: "h-7 w-full" }), _jsx(Skeleton, { className: "h-7 w-full" }), _jsx(Skeleton, { className: "h-7 w-full" })] })] })) : null, connectFlow.connecting &&
|
|
656
883
|
(builderCancelRequested ? (_jsxs("div", { className: "mt-4 flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-sm text-muted-foreground", "data-testid": "first-run-cancel-pending", children: t("agentChat.onboarding.builderCancelPending") }), _jsx("button", { type: "button", "data-testid": "first-run-back-to-choice", className: secondaryButtonClass, onClick: returnToSetupChoice, children: t("agentChat.onboarding.back") })] })) : (_jsx("button", { type: "button", "data-testid": "first-run-cancel-builder", className: "fixed bottom-6 left-6 inline-flex min-h-6 items-center px-2 rounded-sm text-xs font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: () => {
|
|
657
884
|
setBuilderCancelRequested(true);
|
|
658
885
|
connectFlow.cancel();
|
|
659
886
|
}, children: t("common.cancel") }))), connectFlow.statusUnavailable &&
|
|
660
887
|
connectFlow.connecting &&
|
|
661
888
|
!connectFlow.terminalError && (_jsx("p", { className: "mt-4 text-xs text-destructive", role: "alert", children: t("agentChat.settingsShell.integrations.builderStatusFailed") })), connectFlow.terminalError && connectFlow.connecting && (_jsx("p", { className: "mt-4 text-xs text-destructive", role: "alert", children: connectFlow.terminalError })), !connectFlow.connecting &&
|
|
889
|
+
!provisioningFailed &&
|
|
662
890
|
(connectFlow.statusUnavailable || connectFlow.terminalError) && (_jsxs("div", { className: "mt-4 flex flex-col items-center gap-2", children: [_jsx("p", { className: "text-xs text-destructive", role: "alert", children: connectFlow.terminalError ??
|
|
663
|
-
t("agentChat.settingsShell.integrations.builderStatusFailed") }), _jsx("button", { type: "button", className: secondaryButtonClass, onClick: () => handleBuilder(builderConnectionMode === "provision"), children: "Try again" }), _jsx("button", { type: "button", "data-testid": "first-run-back-to-choice", className: secondaryButtonClass, onClick: returnToSetupChoice, children: t("agentChat.onboarding.back") })] })), !connectFlow.connecting &&
|
|
891
|
+
t("agentChat.settingsShell.integrations.builderStatusFailed") }), _jsx("button", { type: "button", className: secondaryButtonClass, onClick: () => handleBuilder(builderConnectionMode === "provision"), children: "Try again" }), _jsx("button", { type: "button", "data-testid": "first-run-back-to-choice", className: secondaryButtonClass, onClick: returnToSetupChoice, children: t("agentChat.onboarding.back") })] })), provisioningFailed ? (_jsxs("div", { className: "mt-4 flex w-full flex-col items-center gap-2", children: [_jsx("button", { type: "button", "data-testid": "first-run-retry-builder", className: cn(ONBOARDING_PRIMARY_BUTTON_CLASS, "w-full"), onClick: () => handleBuilder(true), children: t("agentChat.settingsShell.builder.retry") }), _jsx("button", { type: "button", "data-testid": "first-run-open-key-settings-after-failure", className: cn(secondaryButtonClass, "w-full"), onClick: () => void handleOpenSettings(), children: t("agentChat.onboarding.openAiKeySettings") }), _jsx("button", { type: "button", "data-testid": "first-run-skip-builder-after-failure", className: "inline-flex min-h-9 items-center justify-center rounded-lg px-2.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: skipFailedBuilderSetup, children: t("agentChat.onboarding.skipForNow") })] })) : null, !connectFlow.connecting &&
|
|
664
892
|
!connectFlow.statusUnavailable &&
|
|
665
893
|
!connectFlow.terminalError && (_jsx("button", { type: "button", "data-testid": "first-run-back-to-choice", className: "fixed bottom-6 left-6 inline-flex min-h-6 items-center px-2 rounded-sm text-xs font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", onClick: returnToSetupChoice, children: t("agentChat.onboarding.back") }))] })), accountExists && !connectFlow.connecting && (_jsx("button", { type: "button", "data-testid": "first-run-back-to-choice", className: cn(secondaryButtonClass, "mt-3"), onClick: returnToSetupChoice, children: t("agentChat.onboarding.back") }))] }) }));
|
|
666
894
|
}
|