diff --git a/apps/server/src/provider/ClaudeProvider.ts b/apps/server/src/provider/ClaudeProvider.ts index 18f3b8508a04a..8f594b9594ab0 100644 --- a/apps/server/src/provider/ClaudeProvider.ts +++ b/apps/server/src/provider/ClaudeProvider.ts @@ -637,6 +637,7 @@ export const checkClaudeProviderStatus = Effect.fn("checkClaudeProviderStatus")( enabled: claudeSettings.enabled, checkedAt, models, + updateRequiredModels, slashCommands: dedupedSlashCommands, skills, probe: { diff --git a/apps/server/src/provider/ProviderRegistry.test.ts b/apps/server/src/provider/ProviderRegistry.test.ts index a278470c286d0..5e67ebdf85670 100644 --- a/apps/server/src/provider/ProviderRegistry.test.ts +++ b/apps/server/src/provider/ProviderRegistry.test.ts @@ -2166,6 +2166,42 @@ it.layer( ), ); + it.effect("tells a logged-out CLI which models need a Claude Code update", () => + Effect.gen(function* () { + const status = yield* checkClaudeProviderStatus( + defaultClaudeSettings, + claudeCapabilities({ + tokenSource: "none", + apiKeySource: "none", + apiProvider: "firstParty", + }), + { ANTHROPIC_BASE_URL: "" }, + undefined, + { + models: [ + { + model: { slug: "claude-next", name: "Next", isCustom: false, capabilities: null }, + runtime: {}, + compatibility: { minVersion: "1.1.0" }, + }, + ], + }, + ); + assert.strictEqual(status.auth.status, "unauthenticated"); + assert.deepStrictEqual(status.updateRequiredModels, [ + { slug: "claude-next", name: "Next", minVersion: "1.1.0" }, + ]); + }).pipe( + Effect.provide( + layerMockSpawner((args) => { + const joined = args.join(" "); + if (joined === "--version") return { stdout: "1.0.0\n", stderr: "", code: 0 }; + throw new Error(`Unexpected args: ${joined}`); + }), + ), + ), + ); + it.effect.each([ { source: "inherited HTTPS endpoint", baseUrl: "https://proxy.example/api", overrides: [] }, {