/** * @license * Copyright 2025 Vybestack LLC * SPDX-License-Identifier: Apache-2.0 */ import type React from 'react'; import { useState, useCallback } from 'react'; import { Box, Text } from 'ink'; import { Colors } from '../../colors.js'; import { useKeypress } from '../../hooks/useKeypress.js'; interface CompletionStepProps { provider: string; model?: string; authMethod: 'oauth' | 'api_key'; onSaveProfile: (name: string) => Promise; onDismiss: () => void; isFocused?: boolean; } const CompletionHeader: React.FC<{ providerDisplay: string; model?: string; authDisplay: string; }> = ({ providerDisplay, model, authDisplay }) => ( Step 5 of 5: Save Your Profile {'✓ Authentication complete!'} Provider: {providerDisplay} {model && Model: {model}} Authentication: {authDisplay} ); const ProfileNameInput: React.FC<{ profileName: string; error?: string; saving: boolean; }> = ({ profileName, error, saving }) => ( {error && ( {error} )} {saving ? ( Saving profile... ) : ( Profile name: {profileName} )} ); const ProfilePromptContent: React.FC<{ profileName: string; error?: string; saving: boolean; }> = ({ profileName, error, saving }) => ( Save this setup as a profile This profile will be loaded automatically on startup. Use /profile load <name> to switch profiles later. Enter a name and press Enter to save ); const CompletionSuccessContent: React.FC = () => ( Try asking me something like: {'"Explain how async/await works in JavaScript"'} Press Enter to continue... ); export const CompletionStep: React.FC = ({ provider, model, authMethod, onSaveProfile, onDismiss, isFocused = true, }) => { const [showProfilePrompt, setShowProfilePrompt] = useState(true); const [profileName, setProfileName] = useState(''); const [saving, setSaving] = useState(false); const [error, setError] = useState(); const providerDisplay = provider.charAt(0).toUpperCase() + provider.slice(1); const authDisplay = authMethod === 'oauth' ? 'OAuth' : 'API Key'; const handleProfileSubmit = useCallback(async () => { const trimmedName = profileName.trim(); if (!trimmedName) { setError('Profile name is required'); return; } setSaving(true); setError(undefined); try { await onSaveProfile(trimmedName); setShowProfilePrompt(false); } catch (err: unknown) { setError(err instanceof Error ? err.message : 'Failed to save profile'); setSaving(false); } }, [profileName, onSaveProfile]); useKeypress( (key) => { if (key.name === 'return') { if (showProfilePrompt && !saving) { void handleProfileSubmit(); } else if (!showProfilePrompt) { onDismiss(); } return; } if (!showProfilePrompt || saving) return; if (key.name === 'backspace' || key.name === 'delete') { setProfileName((prev) => prev.slice(0, -1)); return; } const char = key.sequence; if (char && !key.ctrl && !key.meta) { const printable = char.replace(/[^\x20-\x7E]/g, ''); if (printable) { setProfileName((prev) => prev + printable); } } }, { isActive: isFocused }, ); return ( {showProfilePrompt ? ( ) : ( )} ); };