From ff42dccb581adc88ab248cb2c6d8dd6b0377f111 Mon Sep 17 00:00:00 2001 From: deseltrus <101901449+deseltrus@users.noreply.github.com> Date: Mon, 13 Apr 2026 12:46:58 +0200 Subject: [PATCH] fix: persist defaultProvider when user selects Claude Code CLI in onboarding (#4104) The claude-cli onboarding path stored the auth sentinel for claude-code but did not update defaultProvider in settings.json. Users who had an existing Anthropic API key were left on the "anthropic" provider because the startup migration in cli.ts correctly skips direct-key holders. Write defaultProvider = "claude-code" to settings.json in the claude-cli branch so the provider switch takes effect immediately. Co-authored-by: Claude Opus 4.6 (1M context) --- src/onboarding.ts | 9 ++++++ .../onboarding-claude-cli-provider.test.ts | 31 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/tests/onboarding-claude-cli-provider.test.ts diff --git a/src/onboarding.ts b/src/onboarding.ts index d51d408dc..a47d29498 100644 --- a/src/onboarding.ts +++ b/src/onboarding.ts @@ -323,6 +323,15 @@ async function runLlmStep(p: ClackModule, pc: PicoModule, authStorage: AuthStora p.log.info('Your Claude subscription will be used for inference. No API key needed.') // Store sentinel so hasAuth('claude-code') returns true on future boots authStorage.set('claude-code', { type: 'api_key', key: 'cli' }) + // Persist claude-code as the default provider so the startup migration in + // cli.ts does not need to fire and the user is not left on "anthropic". + const settingsPath = join(agentDir, 'settings.json') + try { + const raw = existsSync(settingsPath) ? JSON.parse(readFileSync(settingsPath, 'utf-8')) : {} + raw.defaultProvider = 'claude-code' + mkdirSync(dirname(settingsPath), { recursive: true }) + writeFileSync(settingsPath, JSON.stringify(raw, null, 2), 'utf-8') + } catch { /* non-fatal — startup migration will catch it */ } return true } diff --git a/src/tests/onboarding-claude-cli-provider.test.ts b/src/tests/onboarding-claude-cli-provider.test.ts new file mode 100644 index 000000000..fddb8727f --- /dev/null +++ b/src/tests/onboarding-claude-cli-provider.test.ts @@ -0,0 +1,31 @@ +import test from "node:test" +import assert from "node:assert/strict" +import { readFileSync } from "node:fs" +import { join } from "node:path" + +/** + * Source-level regression test: the claude-cli onboarding path must persist + * defaultProvider = 'claude-code' in settings.json so the user is not left + * on the 'anthropic' direct-API provider after selecting Claude Code CLI. + * + * Without this, the auto-migration in cli.ts does not fire when the user + * also has a stored Anthropic API key, leaving them on the wrong provider. + */ +test("onboarding claude-cli path persists defaultProvider to settings.json", () => { + const source = readFileSync( + join(import.meta.dirname, "..", "onboarding.ts"), + "utf-8", + ) + + // The claude-cli branch must write defaultProvider = 'claude-code' to settings.json + const cliBlock = source.slice( + source.indexOf("method === 'claude-cli'"), + source.indexOf("// ── Step 2"), + ) + assert.ok(cliBlock.length > 0, "claude-cli block not found in onboarding.ts") + assert.match( + cliBlock, + /raw\.defaultProvider\s*=\s*['"]claude-code['"]/, + "claude-cli onboarding path must set defaultProvider = 'claude-code' in settings.json", + ) +})