From d1267393a978be24c86121d3f46f7c35f24535cd Mon Sep 17 00:00:00 2001 From: gnanam1990 Date: Wed, 1 Apr 2026 12:17:31 +0530 Subject: [PATCH 1/2] fix: resolve frozen terminal for OpenAI/3P provider users (#3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The showSetupScreens() early return for CLAUDE_CODE_USE_OPENAI skipped all trust state initialization (setSessionTrustAccepted, GrowthBook, getSystemContext), causing downstream config lookups to fail silently. This prevented the REPL component tree from mounting correctly — useInput never fired, stdin stayed in cooked mode, and the terminal appeared frozen. Fix: skip only the UI dialogs (onboarding, trust, MCP approval) for OpenAI provider while still running the critical state initialization that the REPL depends on. Closes #3 Co-Authored-By: Claude Opus 4.6 --- src/interactiveHelpers.tsx | 47 ++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/interactiveHelpers.tsx b/src/interactiveHelpers.tsx index ca3e4275..efa41e3b 100644 --- a/src/interactiveHelpers.tsx +++ b/src/interactiveHelpers.tsx @@ -103,13 +103,16 @@ export async function renderAndRun(root: Root, element: React.ReactNode): Promis } export async function showSetupScreens(root: Root, permissionMode: PermissionMode, allowDangerouslySkipPermissions: boolean, commands?: Command[], claudeInChrome?: boolean, devChannels?: ChannelEntry[]): Promise { if ("production" === 'test' || isEnvTruthy(false) || process.env.IS_DEMO // Skip onboarding in demo mode - || isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI) // Skip onboarding for OpenAI provider ) { return false; } + + const isOpenAIProvider = isEnvTruthy(process.env.CLAUDE_CODE_USE_OPENAI); const config = getGlobalConfig(); let onboardingShown = false; - if (!config.theme || !config.hasCompletedOnboarding // always show onboarding at least once + + // Skip onboarding dialog for OpenAI provider (no Anthropic account needed) + if (!isOpenAIProvider && (!config.theme || !config.hasCompletedOnboarding) // always show onboarding at least once ) { onboardingShown = true; const { @@ -130,10 +133,9 @@ export async function showSetupScreens(root: Root, permissionMode: PermissionMod // Note: non-interactive sessions (CI/CD with -p) never reach showSetupScreens at all. // Skip permission checks in claubbit if (!isEnvTruthy(process.env.CLAUBBIT)) { - // Fast-path: skip TrustDialog import+render when CWD is already trusted. - // If it returns true, the TrustDialog would auto-resolve regardless of - // security features, so we can skip the dynamic import and render cycle. - if (!checkHasTrustDialogAccepted()) { + // Skip trust dialog UI for OpenAI provider (no Anthropic auth), but still + // run trust state initialization below so the REPL mounts correctly. + if (!isOpenAIProvider && !checkHasTrustDialogAccepted()) { const { TrustDialog } = await import('./components/TrustDialog/TrustDialog.js'); @@ -142,6 +144,8 @@ export async function showSetupScreens(root: Root, permissionMode: PermissionMod // Signal that trust has been verified for this session. // GrowthBook checks this to decide whether to include auth headers. + // Critical for OpenAI provider: without this, downstream config lookups + // may fail silently, preventing the REPL from mounting (frozen terminal). setSessionTrustAccepted(true); // Reset and reinitialize GrowthBook after trust is established. @@ -153,21 +157,24 @@ export async function showSetupScreens(root: Root, permissionMode: PermissionMod // Now that trust is established, prefetch system context if it wasn't already void getSystemContext(); - // If settings are valid, check for any mcp.json servers that need approval - const { - errors: allErrors - } = getSettingsWithAllErrors(); - if (allErrors.length === 0) { - await handleMcpjsonServerApprovals(root); - } - - // Check for claude.md includes that need approval - if (await shouldShowClaudeMdExternalIncludesWarning()) { - const externalIncludes = getExternalClaudeMdIncludes(await getMemoryFiles(true)); + // Skip MCP approval dialogs for OpenAI provider (no interactive auth prompts) + if (!isOpenAIProvider) { + // If settings are valid, check for any mcp.json servers that need approval const { - ClaudeMdExternalIncludesDialog - } = await import('./components/ClaudeMdExternalIncludesDialog.js'); - await showSetupDialog(root, done => ); + errors: allErrors + } = getSettingsWithAllErrors(); + if (allErrors.length === 0) { + await handleMcpjsonServerApprovals(root); + } + + // Check for claude.md includes that need approval + if (await shouldShowClaudeMdExternalIncludesWarning()) { + const externalIncludes = getExternalClaudeMdIncludes(await getMemoryFiles(true)); + const { + ClaudeMdExternalIncludesDialog + } = await import('./components/ClaudeMdExternalIncludesDialog.js'); + await showSetupDialog(root, done => ); + } } } From 6cf95f5b1de011d5e676a3b7c696aa7f62fea692 Mon Sep 17 00:00:00 2001 From: gnanam1990 Date: Wed, 1 Apr 2026 13:23:48 +0530 Subject: [PATCH 2/2] fix: show actual OpenAI model name in welcome screen UI When using OpenAI provider, getPublicModelDisplayName() was incorrectly returning "Opus 4.6" because CLAUDE_OPUS_4_6_CONFIG.openai maps to 'gpt-4o', causing a false match in the switch statement. Now returns null for OpenAI provider so the raw model name (e.g. 'gpt-4o') is displayed directly. Co-Authored-By: Claude Sonnet 4.6 --- src/utils/model/model.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/utils/model/model.ts b/src/utils/model/model.ts index decb34ef..25897b5a 100644 --- a/src/utils/model/model.ts +++ b/src/utils/model/model.ts @@ -193,6 +193,11 @@ export function getRuntimeMainLoopModel(params: { * @returns The default model setting to use */ export function getDefaultMainLoopModelSetting(): ModelName | ModelAlias { + // OpenAI provider: always use the configured OpenAI model + if (getAPIProvider() === 'openai') { + return process.env.OPENAI_MODEL || 'gpt-4o' + } + // Ants default to defaultModel from flag config, or Opus 1M if not configured if (process.env.USER_TYPE === 'ant') { return ( @@ -364,6 +369,10 @@ export function renderModelSetting(setting: ModelName | ModelAlias): string { * if the model is not recognized as a public model. */ export function getPublicModelDisplayName(model: ModelName): string | null { + // For OpenAI provider, show the actual model name (e.g. 'gpt-4o') not a Claude alias + if (getAPIProvider() === 'openai') { + return null + } switch (model) { case getModelStrings().opus46: return 'Opus 4.6'