diff --git a/src/entrypoints/cli.tsx b/src/entrypoints/cli.tsx index e67a8764..4f75d5c3 100644 --- a/src/entrypoints/cli.tsx +++ b/src/entrypoints/cli.tsx @@ -134,6 +134,18 @@ async function main(): Promise { return; } + // --provider: set provider env vars early so saved-profile resolution, + // validation, and the startup banner all see the intended provider/model. + if (args.includes('--provider')) { + const { applyProviderFlagFromArgs } = await import('../utils/providerFlag.js'); + const result = applyProviderFlagFromArgs(args); + if (result?.error) { + // biome-ignore lint/suspicious/noConsole:: intentional error output + console.error(`Error: ${result.error}`); + process.exit(1); + } + } + { const { enableConfigs } = await import('../utils/config.js') enableConfigs() @@ -406,22 +418,6 @@ async function main(): Promise { process.env.CLAUDE_CODE_SIMPLE = '1'; } - // --provider: set provider env vars early, before main module loads. - // This mirrors the --bare pattern: env vars must be in place before - // Commander option building and module-level constants are evaluated. - if (args.includes('--provider')) { - const { parseProviderFlag, applyProviderFlag } = await import('../utils/providerFlag.js'); - const provider = parseProviderFlag(args); - if (provider) { - const result = applyProviderFlag(provider, args); - if (result.error) { - // biome-ignore lint/suspicious/noConsole:: intentional error output - console.error(`Error: ${result.error}`); - process.exit(1); - } - } - } - // No special flags detected, load and run the full CLI if (process.env.OPENCLAUDE_DISABLE_EARLY_INPUT !== '1') { const { diff --git a/src/utils/providerFlag.test.ts b/src/utils/providerFlag.test.ts index 30f392fc..ce58fff6 100644 --- a/src/utils/providerFlag.test.ts +++ b/src/utils/providerFlag.test.ts @@ -1,5 +1,10 @@ import { describe, expect, test, afterEach } from 'bun:test' -import { parseProviderFlag, applyProviderFlag, VALID_PROVIDERS } from './providerFlag.js' +import { + parseProviderFlag, + applyProviderFlag, + applyProviderFlagFromArgs, + VALID_PROVIDERS, +} from './providerFlag.js' const originalEnv = { ...process.env } @@ -137,3 +142,23 @@ describe('applyProviderFlag - invalid provider', () => { expect(result.error).toContain(VALID_PROVIDERS.join(', ')) }) }) + +describe('applyProviderFlagFromArgs', () => { + test('applies ollama provider and model from argv in one step', () => { + const result = applyProviderFlagFromArgs([ + '--provider', + 'ollama', + '--model', + 'qwen2.5:3b', + ]) + + expect(result?.error).toBeUndefined() + expect(process.env.CLAUDE_CODE_USE_OPENAI).toBe('1') + expect(process.env.OPENAI_BASE_URL).toBe('http://localhost:11434/v1') + expect(process.env.OPENAI_MODEL).toBe('qwen2.5:3b') + }) + + test('returns undefined when --provider is absent', () => { + expect(applyProviderFlagFromArgs(['--model', 'gpt-4o'])).toBeUndefined() + }) +}) diff --git a/src/utils/providerFlag.ts b/src/utils/providerFlag.ts index 6a56eca0..b2cbc06f 100644 --- a/src/utils/providerFlag.ts +++ b/src/utils/providerFlag.ts @@ -35,6 +35,18 @@ export function parseProviderFlag(args: string[]): string | null { return value } +/** + * Parse and apply --provider from argv in one step. + * Returns undefined when the flag is absent. + */ +export function applyProviderFlagFromArgs( + args: string[], +): { error?: string } | undefined { + const provider = parseProviderFlag(args) + if (!provider) return undefined + return applyProviderFlag(provider, args) +} + /** * Extract the value of --model from argv. * Returns null if absent.