diff --git a/apps/x/apps/renderer/src/components/onboarding/steps/llm-setup-step.tsx b/apps/x/apps/renderer/src/components/onboarding/steps/llm-setup-step.tsx index 86787753..fa7ee93c 100644 --- a/apps/x/apps/renderer/src/components/onboarding/steps/llm-setup-step.tsx +++ b/apps/x/apps/renderer/src/components/onboarding/steps/llm-setup-step.tsx @@ -39,9 +39,14 @@ export function LlmSetupStep({ state }: LlmSetupStepProps) { updateProviderConfig, handleTestAndSaveLlmConfig, handleTestAndAddAnother, connectedFlavors, handleNext, handleBack, upsellDismissed, setUpsellDismissed, handleSwitchToRowboat, + chatgpt, } = state const isMoreProvider = moreProviders.some(p => p.id === llmProvider) + // "Sign in with ChatGPT" (below the OpenAI card) is an alternative to a key: + // signing in counts as a connected provider alongside any saved BYOK one, + // which is what unlocks Continue when no API key was entered. + const hasConnectedProvider = connectedFlavors.size > 0 || chatgpt.status.signedIn // Connect-only, mirroring Settings: entering a key (or base URL) is enough // and the model is resolved silently at save. openai-compatible is the sole // exception with a visible Model field — its /models endpoint often doesn't @@ -188,6 +193,56 @@ export function LlmSetupStep({ state }: LlmSetupStepProps) { )} + {/* ChatGPT subscription — OAuth sign-in shown under the OpenAI card, + mirroring Settings (settings-dialog.tsx, gated on provider === + "openai"). Alternative to an API key: signs in via the shared + chatgpt:* path, independent of models.json (the Codex model client + consumes the token in core). */} + {llmProvider === "openai" && ( +
+ + {chatgpt.status.signedIn ? ( +
+
+ + + Connected as {chatgpt.status.email ?? "your ChatGPT account"} + +
+ +
+ ) : chatgpt.isSigningIn ? ( +
+
+ + Waiting for browser… +
+ +
+ ) : ( +
+ + Use your ChatGPT Plus/Pro subscription + + +
+ )} +
+ )} + {showBaseURL && (