diff --git a/packages/cli/src/ui/components/WelcomeOnboarding/AuthMethodStep.tsx b/packages/cli/src/ui/components/WelcomeOnboarding/AuthMethodStep.tsx index 6271d844e..43d6ad597 100644 --- a/packages/cli/src/ui/components/WelcomeOnboarding/AuthMethodStep.tsx +++ b/packages/cli/src/ui/components/WelcomeOnboarding/AuthMethodStep.tsx @@ -88,8 +88,9 @@ export const AuthMethodStep: React.FC = ({ Step 3 of 5: Choose Authentication Method - - How would you like to authenticate with {providerDisplay}? + + How would you like to authenticate with {providerDisplay}? + {error && ( diff --git a/packages/cli/src/ui/components/WelcomeOnboarding/AuthenticationStep.tsx b/packages/cli/src/ui/components/WelcomeOnboarding/AuthenticationStep.tsx index bc75f05c6..d298b41d1 100644 --- a/packages/cli/src/ui/components/WelcomeOnboarding/AuthenticationStep.tsx +++ b/packages/cli/src/ui/components/WelcomeOnboarding/AuthenticationStep.tsx @@ -119,12 +119,18 @@ export const AuthenticationStep: React.FC = ({ {' '} - Opening browser for OAuth authentication... + + Opening browser for OAuth authentication... + - Please complete the authentication in your browser. - This window will update when done. + + Please complete the authentication in your browser. + + + This window will update when done. + Press Esc to cancel and go back @@ -149,18 +155,20 @@ export const AuthenticationStep: React.FC = ({ {' '} - Validating API key... + Validating API key... ) : ( <> - Enter your {providerDisplay} API key: + + Enter your {providerDisplay} API key: + - API Key: - {maskedValue} + API Key: + {maskedValue} diff --git a/packages/cli/src/ui/components/WelcomeOnboarding/CompletionStep.tsx b/packages/cli/src/ui/components/WelcomeOnboarding/CompletionStep.tsx index 7fe060fb1..543b51b19 100644 --- a/packages/cli/src/ui/components/WelcomeOnboarding/CompletionStep.tsx +++ b/packages/cli/src/ui/components/WelcomeOnboarding/CompletionStep.tsx @@ -94,22 +94,23 @@ export const CompletionStep: React.FC = ({ Step 5 of 5: Save Your Profile - - {'✓ Authentication complete!'} + [OK] Authentication complete! - Provider: {providerDisplay} - {model && Model: {model}} - Authentication: {authDisplay} + Provider: {providerDisplay} + {model && Model: {model}} + Authentication: {authDisplay} {showProfilePrompt ? ( - Save this setup as a profile + + Save this setup as a profile + @@ -127,11 +128,11 @@ export const CompletionStep: React.FC = ({ )} {saving ? ( - Saving profile... + Saving profile... ) : ( - Profile name: - {profileName} + Profile name: + {profileName} )} @@ -146,7 +147,7 @@ export const CompletionStep: React.FC = ({ ) : ( - Try asking me something like: + Try asking me something like: {'"Explain how async/await works in JavaScript"'} diff --git a/packages/cli/src/ui/components/WelcomeOnboarding/ModelSelectStep.tsx b/packages/cli/src/ui/components/WelcomeOnboarding/ModelSelectStep.tsx index bfda951d2..0d25194e3 100644 --- a/packages/cli/src/ui/components/WelcomeOnboarding/ModelSelectStep.tsx +++ b/packages/cli/src/ui/components/WelcomeOnboarding/ModelSelectStep.tsx @@ -80,8 +80,10 @@ export const ModelSelectStep: React.FC = ({ Step 2 of 5: Choose Your Model - - Select a model for {providerDisplay}: + + {' '} + Select a model for {providerDisplay}: + {modelsLoadStatus === 'loading' && ( diff --git a/packages/cli/src/ui/components/WelcomeOnboarding/ProviderSelectStep.tsx b/packages/cli/src/ui/components/WelcomeOnboarding/ProviderSelectStep.tsx index 72f4dde69..8e22a37bc 100644 --- a/packages/cli/src/ui/components/WelcomeOnboarding/ProviderSelectStep.tsx +++ b/packages/cli/src/ui/components/WelcomeOnboarding/ProviderSelectStep.tsx @@ -69,8 +69,9 @@ export const ProviderSelectStep: React.FC = ({ Step 1 of 5: Choose Your AI Provider - - {"Select which AI provider you'd like to use:"} + + {"Select which AI provider you'd like to use:"} + = ({ return ( - Setup skipped + + Setup skipped + - To configure llxprt manually: - - + To configure llxprt manually: + • Use /auth <provider> to set up authentication - + • Use /provider to select your AI provider - + • Type /help for more commands diff --git a/packages/cli/src/ui/components/WelcomeOnboarding/WelcomeStep.tsx b/packages/cli/src/ui/components/WelcomeOnboarding/WelcomeStep.tsx index faee3db25..f2f7bcd1a 100644 --- a/packages/cli/src/ui/components/WelcomeOnboarding/WelcomeStep.tsx +++ b/packages/cli/src/ui/components/WelcomeOnboarding/WelcomeStep.tsx @@ -42,16 +42,20 @@ export const WelcomeStep: React.FC = ({ Welcome to llxprt! - - {"Let's get you set up in just a few steps."} - + + {' '} + {"Let's get you set up in just a few steps."} + + {"You'll choose an AI provider and configure authentication"} - so llxprt can work its magic. + so llxprt can work its magic. - What would you like to do? + + What would you like to do? + { + return PLACEHOLDER_MODEL_NAMES.has(modelName); + }, []); + + const shouldSuppressWelcome = useMemo(() => { + // Always prefer showing onboarding until the user explicitly completes/skips it. + if (!isFolderTrustComplete || welcomeCompleted) { + return false; + } + + // Non-interactive signals (CLI/env) that indicate the user already configured things. + // Keep this conservative: avoid treating system defaults as user configuration. + + if (process.env.LLXPRT_PROFILE) { + debug.log('Welcome suppressed: LLXPRT_PROFILE environment variable set'); + return true; + } + + // If a provider is already active (typically set via CLI flags or prior usage), + // suppress welcome. + const providerManager = runtime.getCliProviderManager(); + if (providerManager) { + try { + const providerName = providerManager.getActiveProviderName(); + const hasActiveProvider = + providerManager.hasActiveProvider?.() ?? false; + + if (providerName || hasActiveProvider) { + debug.log('Welcome suppressed: active provider configured'); + return true; + } + } catch (error) { + debug.log('Could not check for active provider:', error); + } + } + + try { + const activeModel = runtime.getActiveModelName(); + if (activeModel && !isSystemDefaultModelName(activeModel)) { + debug.log('Welcome suppressed: active model configured'); + return true; + } + } catch (error) { + debug.log('Could not check for active model:', error); + } + + // Intentionally do NOT suppress based solely on defaultProfile. A profile can be + // present due to system defaults and should not skip onboarding unless the user + // has explicitly completed it. + + return false; + }, [ + isFolderTrustComplete, + isSystemDefaultModelName, + runtime, + welcomeCompleted, + ]); + + // Show welcome after folder trust is complete unless it was completed/skipped, + // or we detect a non-interactive configuration state. + const showWelcome = + !welcomeCompleted && isFolderTrustComplete && !shouldSuppressWelcome; const [state, setState] = useState({ step: 'welcome',