mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-10 00:31:22 +00:00
feat: add anthropic claude cli migration
This commit is contained in:
19
src/commands/auth-choice-legacy.test.ts
Normal file
19
src/commands/auth-choice-legacy.test.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
formatDeprecatedNonInteractiveAuthChoiceError,
|
||||
normalizeLegacyOnboardAuthChoice,
|
||||
resolveDeprecatedAuthChoiceReplacement,
|
||||
} from "./auth-choice-legacy.js";
|
||||
|
||||
describe("auth choice legacy aliases", () => {
|
||||
it("maps claude-cli to the new anthropic cli choice", () => {
|
||||
expect(normalizeLegacyOnboardAuthChoice("claude-cli")).toBe("anthropic-cli");
|
||||
expect(resolveDeprecatedAuthChoiceReplacement("claude-cli")).toEqual({
|
||||
normalized: "anthropic-cli",
|
||||
message: 'Auth choice "claude-cli" is deprecated; using Anthropic Claude CLI setup instead.',
|
||||
});
|
||||
expect(formatDeprecatedNonInteractiveAuthChoiceError("claude-cli")).toBe(
|
||||
'Auth choice "claude-cli" is deprecated.\nUse "--auth-choice anthropic-cli".',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -10,9 +10,12 @@ export const AUTH_CHOICE_LEGACY_ALIASES_FOR_CLI: ReadonlyArray<AuthChoice> = [
|
||||
export function normalizeLegacyOnboardAuthChoice(
|
||||
authChoice: AuthChoice | undefined,
|
||||
): AuthChoice | undefined {
|
||||
if (authChoice === "oauth" || authChoice === "claude-cli") {
|
||||
if (authChoice === "oauth") {
|
||||
return "setup-token";
|
||||
}
|
||||
if (authChoice === "claude-cli") {
|
||||
return "anthropic-cli";
|
||||
}
|
||||
if (authChoice === "codex-cli") {
|
||||
return "openai-codex";
|
||||
}
|
||||
@@ -31,8 +34,8 @@ export function resolveDeprecatedAuthChoiceReplacement(authChoice: "claude-cli"
|
||||
} {
|
||||
if (authChoice === "claude-cli") {
|
||||
return {
|
||||
normalized: "setup-token",
|
||||
message: 'Auth choice "claude-cli" is deprecated; using setup-token flow instead.',
|
||||
normalized: "anthropic-cli",
|
||||
message: 'Auth choice "claude-cli" is deprecated; using Anthropic Claude CLI setup instead.',
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -45,8 +48,6 @@ export function formatDeprecatedNonInteractiveAuthChoiceError(
|
||||
authChoice: "claude-cli" | "codex-cli",
|
||||
): string {
|
||||
const replacement =
|
||||
authChoice === "claude-cli"
|
||||
? '"--auth-choice token" (Anthropic setup-token)'
|
||||
: '"--auth-choice openai-codex"';
|
||||
authChoice === "claude-cli" ? '"--auth-choice anthropic-cli"' : '"--auth-choice openai-codex"';
|
||||
return [`Auth choice "${authChoice}" is deprecated.`, `Use ${replacement}.`].join("\n");
|
||||
}
|
||||
|
||||
@@ -229,6 +229,52 @@ describe("modelsAuthLoginCommand", () => {
|
||||
expect(runtime.log).toHaveBeenCalledWith("Default model set to openai-codex/gpt-5.4");
|
||||
});
|
||||
|
||||
it("supports provider-owned Claude CLI migration without writing auth profiles", async () => {
|
||||
const runtime = createRuntime();
|
||||
const runClaudeCliMigration = vi.fn().mockResolvedValue({
|
||||
profiles: [],
|
||||
defaultModel: "claude-cli/claude-sonnet-4-6",
|
||||
configPatch: {
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"claude-cli/claude-sonnet-4-6": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
mocks.resolvePluginProviders.mockReturnValue([
|
||||
{
|
||||
id: "anthropic",
|
||||
label: "Anthropic",
|
||||
auth: [
|
||||
{
|
||||
id: "cli",
|
||||
label: "Claude CLI",
|
||||
kind: "custom",
|
||||
run: runClaudeCliMigration,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
await modelsAuthLoginCommand(
|
||||
{ provider: "anthropic", method: "cli", setDefault: true },
|
||||
runtime,
|
||||
);
|
||||
|
||||
expect(runClaudeCliMigration).toHaveBeenCalledOnce();
|
||||
expect(mocks.upsertAuthProfile).not.toHaveBeenCalled();
|
||||
expect(lastUpdatedConfig?.agents?.defaults?.model).toEqual({
|
||||
primary: "claude-cli/claude-sonnet-4-6",
|
||||
});
|
||||
expect(lastUpdatedConfig?.agents?.defaults?.models).toEqual({
|
||||
"claude-cli/claude-sonnet-4-6": {},
|
||||
});
|
||||
expect(runtime.log).toHaveBeenCalledWith("Default model set to claude-cli/claude-sonnet-4-6");
|
||||
});
|
||||
|
||||
it("clears stale auth lockouts before attempting openai-codex login", async () => {
|
||||
const runtime = createRuntime();
|
||||
const fakeStore = {
|
||||
|
||||
@@ -9,6 +9,7 @@ export type { AuthProfileStore, OAuthCredential } from "../agents/auth-profiles/
|
||||
export { CLAUDE_CLI_PROFILE_ID, CODEX_CLI_PROFILE_ID } from "../agents/auth-profiles/constants.js";
|
||||
export { ensureAuthProfileStore } from "../agents/auth-profiles/store.js";
|
||||
export { listProfilesForProvider, upsertAuthProfile } from "../agents/auth-profiles/profiles.js";
|
||||
export { readClaudeCliCredentialsCached } from "../agents/cli-credentials.js";
|
||||
export { suggestOAuthProfileIdForLegacyDefault } from "../agents/auth-profiles/repair.js";
|
||||
export {
|
||||
MINIMAX_OAUTH_MARKER,
|
||||
|
||||
@@ -510,6 +510,7 @@ describe("plugin-sdk subpath exports", () => {
|
||||
expectSourceMentions("provider-auth", [
|
||||
"buildOauthProviderAuthResult",
|
||||
"generatePkceVerifierChallenge",
|
||||
"readClaudeCliCredentialsCached",
|
||||
"toFormUrlEncoded",
|
||||
]);
|
||||
expectSourceOmits("core", ["buildOauthProviderAuthResult"]);
|
||||
|
||||
@@ -174,6 +174,16 @@ export const GENERATED_BUNDLED_PLUGIN_METADATA = [
|
||||
anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"],
|
||||
},
|
||||
providerAuthChoices: [
|
||||
{
|
||||
provider: "anthropic",
|
||||
method: "cli",
|
||||
choiceId: "anthropic-cli",
|
||||
choiceLabel: "Anthropic Claude CLI",
|
||||
choiceHint: "Reuse a local Claude CLI login on this host",
|
||||
groupId: "anthropic",
|
||||
groupLabel: "Anthropic",
|
||||
groupHint: "Claude CLI + setup-token + API key",
|
||||
},
|
||||
{
|
||||
provider: "anthropic",
|
||||
method: "setup-token",
|
||||
@@ -182,7 +192,7 @@ export const GENERATED_BUNDLED_PLUGIN_METADATA = [
|
||||
choiceHint: "Run `claude setup-token` elsewhere, then paste the token here",
|
||||
groupId: "anthropic",
|
||||
groupLabel: "Anthropic",
|
||||
groupHint: "setup-token + API key",
|
||||
groupHint: "Claude CLI + setup-token + API key",
|
||||
},
|
||||
{
|
||||
provider: "anthropic",
|
||||
@@ -191,7 +201,7 @@ export const GENERATED_BUNDLED_PLUGIN_METADATA = [
|
||||
choiceLabel: "Anthropic API key",
|
||||
groupId: "anthropic",
|
||||
groupLabel: "Anthropic",
|
||||
groupHint: "setup-token + API key",
|
||||
groupHint: "Claude CLI + setup-token + API key",
|
||||
optionKey: "anthropicApiKey",
|
||||
cliFlag: "--anthropic-api-key",
|
||||
cliOption: "--anthropic-api-key <key>",
|
||||
|
||||
Reference in New Issue
Block a user