From a33063fbad2970ef123127ac1bbd2e97fef4550f Mon Sep 17 00:00:00 2001 From: Askhz <1361267452@qq.com> Date: Thu, 9 Apr 2026 21:10:32 +0800 Subject: [PATCH] refactor: remove OAuth/preflight from onboarding and fix model picker reload after CoStrict login - Remove preflight and OAuth steps from onboarding flow - Clear both modelType and model settings on logout - Reload ModelPicker via key after successful CoStrict login instead of closing it - Pre-fetch and cache CoStrict models silently after login --- src/commands/logout/logout.tsx | 2 +- src/commands/model/model.tsx | 22 +++++++------------ src/components/Onboarding.tsx | 40 +++++----------------------------- 3 files changed, 15 insertions(+), 49 deletions(-) diff --git a/src/commands/logout/logout.tsx b/src/commands/logout/logout.tsx index e06c6cd83..bfa2a2be9 100644 --- a/src/commands/logout/logout.tsx +++ b/src/commands/logout/logout.tsx @@ -32,7 +32,7 @@ export async function performLogout({ clearOnboarding = false }): Promise await deleteCoStrictCredentials(); clearModelCache(); delete process.env.CLAUDE_CODE_USE_COSTRICT; - updateSettingsForSource('userSettings', { modelType: 'anthropic' as any }); + updateSettingsForSource('userSettings', { modelType: undefined, model: undefined } as any); await clearAuthRelatedCaches(); saveGlobalConfig(current => { diff --git a/src/commands/model/model.tsx b/src/commands/model/model.tsx index d87861464..4a6114fde 100644 --- a/src/commands/model/model.tsx +++ b/src/commands/model/model.tsx @@ -47,6 +47,7 @@ function ModelPickerWrapper({ const mainLoopModelForSession = useAppState(s => s.mainLoopModelForSession); const isFastMode = useAppState(s => s.fastMode); const setAppState = useSetAppState(); + const [pickerKey, setPickerKey] = React.useState(0); function handleCancel(): void { logEvent('tengu_model_command_menu', { @@ -69,11 +70,9 @@ function ModelPickerWrapper({ const machineId = generateMachineId(); const loginUrl = buildCoStrictLoginURL(baseUrl, state, machineId); - // 打开浏览器 + // 打开浏览器(不调用 onDone,保持 picker 显示) await openBrowser(loginUrl); - onDone('Opening browser for CoStrict login...', { display: 'system' }); - // 轮询等待登录完成 const tokens = await pollLoginToken(baseUrl, state, machineId); @@ -96,22 +95,16 @@ function ModelPickerWrapper({ updateSettingsForSource('userSettings', { modelType: 'costrict' as any } as any); process.env.CLAUDE_CODE_USE_COSTRICT = '1'; - // 预取模型列表 + // 预取并缓存模型列表 try { const { fetchCoStrictModels } = await import('../../costrict/provider/models.js'); - const models = await fetchCoStrictModels(baseUrl, tokens.access_token); - if (models.length > 0) { - // 登录成功,刷新模型列表 - onDone(`Successfully logged in to CoStrict! Found ${models.length} available models.`, { - display: 'system', - }); - return; - } + await fetchCoStrictModels(baseUrl, tokens.access_token); } catch { - // 预取失败 + // 预取失败,picker 重载后会显示默认模型列表 } - onDone('Successfully logged in to CoStrict!', { display: 'system' }); + // 登录成功后重载 ModelPicker,显示 CoStrict 模型选择界面 + setPickerKey(k => k + 1); } catch (err: any) { onDone(`Login failed: ${err.message || String(err)}`, { display: 'system' }); } @@ -166,6 +159,7 @@ function ModelPickerWrapper({ return ( isAnthropicAuthEnabled()) const [theme, setTheme] = useTheme() useEffect(() => { - logEvent('tengu_began_setup', { - oauthEnabled, - }) - }, [oauthEnabled]) + logEvent('tengu_began_setup', {}) + }, []) function goToNextStep() { if (currentStepIndex < steps.length - 1) { @@ -60,7 +51,6 @@ export function Onboarding({ onDone }: Props): React.ReactNode { setCurrentStepIndex(nextIndex) logEvent('tengu_onboarding_step', { - oauthEnabled, stepId: steps[nextIndex] ?.id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, }) @@ -123,8 +113,7 @@ export function Onboarding({ onDone }: Props): React.ReactNode { ) - const preflightStep = - // Create the steps array - determine which steps to include based on reAuth and oauthEnabled + // Create the steps array const apiKeyNeedingApproval = useMemo(() => { // Add API key step if needed // On homespace, ANTHROPIC_API_KEY is preserved in process.env for child @@ -140,17 +129,11 @@ export function Onboarding({ onDone }: Props): React.ReactNode { } }, []) - function handleApiKeyDone(approved: boolean) { - if (approved) { - setSkipOAuth(true) - } + function handleApiKeyDone(_approved: boolean) { goToNextStep() } const steps: OnboardingStep[] = [] - if (oauthEnabled) { - steps.push({ id: 'preflight', component: preflightStep }) - } steps.push({ id: 'theme', component: themeStep }) if (apiKeyNeedingApproval) { @@ -165,17 +148,6 @@ export function Onboarding({ onDone }: Props): React.ReactNode { }) } - if (oauthEnabled) { - steps.push({ - id: 'oauth', - component: ( - - - - ), - }) - } - steps.push({ id: 'security', component: securityStep }) if (shouldOfferTerminalSetup()) { @@ -239,11 +211,11 @@ export function Onboarding({ onDone }: Props): React.ReactNode { } else { goToNextStep() } - }, [currentStepIndex, steps.length, oauthEnabled, onDone]) + }, [currentStepIndex, steps.length, onDone]) const handleTerminalSetupSkip = useCallback(() => { goToNextStep() - }, [currentStepIndex, steps.length, oauthEnabled, onDone]) + }, [currentStepIndex, steps.length, onDone]) useKeybindings( {