import { c as _c } from "react/compiler-runtime"; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from 'src/services/analytics/index.js'; import { setupTerminal, shouldOfferTerminalSetup } from '../commands/terminalSetup/terminalSetup.js'; import { useExitOnCtrlCDWithKeybindings } from '../hooks/useExitOnCtrlCDWithKeybindings.js'; import { Box, Link, Newline, Text, useTheme } from '../ink.js'; import { useKeybindings } from '../keybindings/useKeybinding.js'; import { isAnthropicAuthEnabled } from '../utils/auth.js'; import { normalizeApiKeyForConfig } from '../utils/authPortable.js'; import { getCustomApiKeyStatus } from '../utils/config.js'; import { env } from '../utils/env.js'; import { isRunningOnHomespace } from '../utils/envUtils.js'; import { PreflightStep } from '../utils/preflightChecks.js'; import type { ThemeSetting } from '../utils/theme.js'; import { ApproveApiKey } from './ApproveApiKey.js'; import { ConsoleOAuthFlow } from './ConsoleOAuthFlow.js'; import { Select } from './CustomSelect/select.js'; import { WelcomeV2 } from './LogoV2/WelcomeV2.js'; import { PressEnterToContinue } from './PressEnterToContinue.js'; import { ThemePicker } from './ThemePicker.js'; import { OrderedList } from './ui/OrderedList.js'; type StepId = 'preflight' | 'theme' | 'oauth' | 'api-key' | 'security' | 'terminal-setup'; interface OnboardingStep { id: StepId; component: React.ReactNode; } type Props = { onDone(): void; }; export function Onboarding({ onDone }: Props): React.ReactNode { const [currentStepIndex, setCurrentStepIndex] = useState(0); const [skipOAuth, setSkipOAuth] = useState(false); const [oauthEnabled] = useState(() => isAnthropicAuthEnabled()); const [theme, setTheme] = useTheme(); useEffect(() => { logEvent('tengu_began_setup', { oauthEnabled }); }, [oauthEnabled]); function goToNextStep() { if (currentStepIndex < steps.length - 1) { const nextIndex = currentStepIndex + 1; setCurrentStepIndex(nextIndex); logEvent('tengu_onboarding_step', { oauthEnabled, stepId: steps[nextIndex]?.id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS }); } else { onDone(); } } function handleThemeSelection(newTheme: ThemeSetting) { setTheme(newTheme); goToNextStep(); } const exitState = useExitOnCtrlCDWithKeybindings(); // Define all onboarding steps const themeStep = ; const securityStep = Security notes: {/** * OrderedList misnumbers items when rendering conditionally, * so put all items in the if/else */} Claude can make mistakes You should always review Claude's responses, especially when running code. Due to prompt injection risks, only use it with code you trust For more details see: ; const preflightStep = ; // Create the steps array - determine which steps to include based on reAuth and oauthEnabled const apiKeyNeedingApproval = useMemo(() => { // Add API key step if needed // On homespace, ANTHROPIC_API_KEY is preserved in process.env for child // processes but ignored by Claude Code itself (see auth.ts). if (!process.env.ANTHROPIC_API_KEY || isRunningOnHomespace()) { return ''; } const customApiKeyTruncated = normalizeApiKeyForConfig(process.env.ANTHROPIC_API_KEY); if (getCustomApiKeyStatus(customApiKeyTruncated) === 'new') { return customApiKeyTruncated; } }, []); function handleApiKeyDone(approved: boolean) { if (approved) { setSkipOAuth(true); } goToNextStep(); } const steps: OnboardingStep[] = []; if (oauthEnabled) { steps.push({ id: 'preflight', component: preflightStep }); } steps.push({ id: 'theme', component: themeStep }); if (apiKeyNeedingApproval) { steps.push({ id: 'api-key', component: }); } if (oauthEnabled) { steps.push({ id: 'oauth', component: }); } steps.push({ id: 'security', component: securityStep }); if (shouldOfferTerminalSetup()) { steps.push({ id: 'terminal-setup', component: Use Claude Code's terminal setup? For the optimal coding experience, enable the recommended settings for your terminal:{' '} {env.terminal === 'Apple_Terminal' ? 'Option+Enter for newlines and visual bell' : 'Shift+Enter for newlines'}