Swadhin Biswas feat: implement mervelas cli engine, built-in tools, and reactive UI · 4/3/2026
0358986
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import {
getAuthTokenSource,
getConfiguredAuthProvider,
getOpenAIApiKeyWithSource,
getOpenCodeApiKeyWithSource,
getNvidiaApiKeyWithSource,
getOpenRouterApiKeyWithSource,
hasAnthropicApiKeyAuth,
} from "./auth.js";
import type { GlobalConfig } from "./config.js";
import { getAPIProvider, type APIProvider } from "./model/providers.js";
export const AUTH_PROVIDER_CHOICES = [
"anthropic",
"openai",
"openrouter",
"opencode",
"nvidia",
] as const;
export type AuthProviderChoice = (typeof AUTH_PROVIDER_CHOICES)[number];
type AuthProviderMetadata = {
id: AuthProviderChoice;
label: string;
description: string;
setupHint: string;
};
const AUTH_PROVIDER_METADATA: Record<AuthProviderChoice, AuthProviderMetadata> =
{
anthropic: {
id: "anthropic",
label: "Anthropic",
description:
"Subscription login, Console API billing, or Anthropic-compatible platforms",
setupHint: "Run /login and choose Anthropic, or use mervelas auth login.",
},
openai: {
id: "openai",
label: "OpenAI / Codex",
description: "Codex login, imported Codex auth, or an OpenAI API key",
setupHint:
"Run /login and choose OpenAI, or set OPENAI_API_KEY / OPENAI_ACCESS_TOKEN / CODEX_ACCESS_TOKEN.",
},
openrouter: {
id: "openrouter",
label: "OpenRouter",
description: "OpenRouter API key using the Responses API integration",
setupHint: "Run /login and choose OpenRouter, or set OPENROUTER_API_KEY.",
},
opencode: {
id: "opencode",
label: "OpenCode Zen",
description:
"Curated OpenCode gateway models, including some free keyless models",
setupHint:
"Run /login and choose OpenCode Zen, set OPENCODE_API_KEY, or use a free keyless Zen model.",
},
nvidia: {
id: "nvidia",
label: "NVIDIA NIM",
description:
"NVIDIA Inference Microservices, offering a variety of LLMs (many available for free)",
setupHint:
"Run /login and choose NVIDIA NIM, set NVIDIA_API_KEY, or use a free keyless NVIDIA NIM model.",
},
};
export function isAuthProviderChoice(
value: string,
): value is AuthProviderChoice {
return AUTH_PROVIDER_CHOICES.includes(value as AuthProviderChoice);
}
export function getAuthProviderMetadata(
provider: AuthProviderChoice,
): AuthProviderMetadata {
return AUTH_PROVIDER_METADATA[provider];
}
export function renderAuthProviderName(provider: AuthProviderChoice): string {
return getAuthProviderMetadata(provider).label;
}
export function getAuthProviderDescription(
provider: AuthProviderChoice,
): string {
return getAuthProviderMetadata(provider).description;
}
export function getProviderSetupHint(provider: AuthProviderChoice): string {
return getAuthProviderMetadata(provider).setupHint;
}
export function hasConfiguredCredentialsForProvider(
provider: AuthProviderChoice,
): boolean {
if (provider === "anthropic") {
return getAuthTokenSource().hasToken || hasAnthropicApiKeyAuth();
}
if (provider === "openai") {
return getOpenAIApiKeyWithSource().source !== "none";
}
if (provider === "openrouter") {
return getOpenRouterApiKeyWithSource().source !== "none";
}
if (provider === "nvidia") {
return getNvidiaApiKeyWithSource().source !== "none";
}
return getOpenCodeApiKeyWithSource().source !== "none";
}
export function getAuthProviderFromApiProvider(
provider: APIProvider,
): AuthProviderChoice {
return provider === "firstParty" ? "anthropic" : provider;
}
export function setPreferredAuthProvider(
config: GlobalConfig,
provider: AuthProviderChoice,
): GlobalConfig {
return {
...config,
authProvider: provider,
};
}
export function getProviderStatusText(): string {
const configuredProvider = getConfiguredAuthProvider();
const activeProvider = getAuthProviderFromApiProvider(getAPIProvider());
const readiness = hasConfiguredCredentialsForProvider(configuredProvider)
? "configured"
: "not configured yet";
if (activeProvider === configuredProvider) {
return `Current provider: ${renderAuthProviderName(configuredProvider)} (${readiness})`;
}
return `Preferred provider: ${renderAuthProviderName(configuredProvider)} (${readiness}) · Active provider: ${renderAuthProviderName(activeProvider)}`;
}