fix(ui): remove quick config API keys card

Remove the misleading API Keys card from the quick settings page.

The card was hardcoded to a fixed env-var provider list and routed all actions to the broad Environment config section, which made the Add/Change affordances look more precise than they were. This removes the dead surface and keeps the quick settings grid focused on meaningful controls.

Verified:
- pnpm test ui/src/ui/views/config-quick.test.ts
- CI passed on PR #71496
This commit is contained in:
Val Alexander
2026-04-25 04:00:53 -05:00
committed by GitHub
parent bf34fde235
commit 6bdf87de87
3 changed files with 3 additions and 84 deletions

View File

@@ -135,11 +135,7 @@ import {
import { renderChat } from "./views/chat.ts";
import { renderCommandPalette } from "./views/command-palette.ts";
import { getPresetById, type ConfigPresetId } from "./views/config-presets.ts";
import {
renderQuickSettings,
type QuickSettingsChannel,
type QuickSettingsApiKey,
} from "./views/config-quick.ts";
import { renderQuickSettings, type QuickSettingsChannel } from "./views/config-quick.ts";
import { renderConfig, type ConfigProps } from "./views/config.ts";
import {
renderCronQuickCreate,
@@ -430,13 +426,6 @@ const KNOWN_CHANNEL_IDS = [
{ id: "imessage", label: "iMessage" },
] as const;
const KNOWN_PROVIDER_KEYS = [
{ provider: "anthropic", label: "Anthropic", envKey: "ANTHROPIC_API_KEY" },
{ provider: "openai", label: "OpenAI", envKey: "OPENAI_API_KEY" },
{ provider: "google", label: "Google", envKey: "GOOGLE_API_KEY" },
{ provider: "openrouter", label: "OpenRouter", envKey: "OPENROUTER_API_KEY" },
] as const;
function formatQuickSettingsLabel(id: string): string {
const trimmed = id.trim();
if (!trimmed) {
@@ -483,20 +472,6 @@ function extractQuickSettingsChannels(state: AppViewState): QuickSettingsChannel
return channels;
}
function extractQuickSettingsApiKeys(state: AppViewState): QuickSettingsApiKey[] {
const config = state.configForm ?? state.configSnapshot?.config;
const env = config && typeof config === "object" ? config.env : null;
const envObj = env && typeof env === "object" ? (env as Record<string, unknown>) : {};
const envVars =
envObj.vars && typeof envObj.vars === "object" ? (envObj.vars as Record<string, unknown>) : {};
return KNOWN_PROVIDER_KEYS.map(({ provider, label, envKey }) => {
const value = typeof envVars[envKey] === "string" ? envVars[envKey] : envObj[envKey];
const isSet = typeof value === "string" && value.trim().length > 0;
const masked = isSet ? `••••${value.slice(-4)}` : undefined;
return { provider, label, masked, isSet };
});
}
function extractMcpServerCount(state: AppViewState): number {
const config = state.configForm ?? state.configSnapshot?.config;
if (!config || typeof config !== "object") {
@@ -987,12 +962,6 @@ export function renderApp(state: AppViewState) {
state.communicationsActiveSection = "channels";
requestHostUpdate?.();
},
apiKeys: extractQuickSettingsApiKeys(state),
onApiKeyChange: () => {
state.configSettingsMode = "advanced";
state.configActiveSection = "env";
requestHostUpdate?.();
},
automation: {
cronJobCount: state.cronJobs?.length ?? 0,
skillCount: state.skillsReport?.skills?.length ?? 0,

View File

@@ -14,8 +14,6 @@ function createProps(overrides: Partial<QuickSettingsProps> = {}): QuickSettings
onFastModeToggle: vi.fn(),
channels: [],
onChannelConfigure: vi.fn(),
apiKeys: [],
onApiKeyChange: vi.fn(),
automation: {
cronJobCount: 0,
skillCount: 0,

View File

@@ -28,13 +28,6 @@ export type QuickSettingsChannel = {
detail?: string;
};
export type QuickSettingsApiKey = {
provider: string;
label: string;
masked?: string;
isSet: boolean;
};
export type QuickSettingsAutomation = {
cronJobCount: number;
skillCount: number;
@@ -60,10 +53,6 @@ export type QuickSettingsProps = {
channels: QuickSettingsChannel[];
onChannelConfigure?: (channelId: string) => void;
// API Keys
apiKeys: QuickSettingsApiKey[];
onApiKeyChange?: (provider: string) => void;
// Automations
automation: QuickSettingsAutomation;
onManageCron?: () => void;
@@ -277,43 +266,6 @@ function renderChannelsCard(props: QuickSettingsProps) {
`;
}
function renderApiKeysCard(props: QuickSettingsProps) {
return html`
<div class="qs-card">
${renderCardHeader(icons.plug, "API Keys")}
<div class="qs-card__body">
${props.apiKeys.length === 0
? html`<div class="qs-empty muted">No API keys configured</div>`
: props.apiKeys.map(
(key) => html`
<div class="qs-row">
<span class="qs-row__label">${key.label}</span>
<span class="qs-row__value">
${key.isSet
? html`
<code class="qs-masked">${key.masked ?? "••••••••"}</code>
<button
class="qs-link-btn"
@click=${() => props.onApiKeyChange?.(key.provider)}
>
Change
</button>
`
: html`<button
class="qs-link-btn"
@click=${() => props.onApiKeyChange?.(key.provider)}
>
Add →
</button>`}
</span>
</div>
`,
)}
</div>
</div>
`;
}
function renderAutomationsCard(props: QuickSettingsProps) {
const { cronJobCount, skillCount, mcpServerCount } = props.automation;
@@ -589,8 +541,8 @@ export function renderQuickSettings(props: QuickSettingsProps) {
<div class="qs-grid">
${renderStack(renderModelCard(props), renderSecurityCard(props))}
${renderStack(renderChannelsCard(props), renderAutomationsCard(props))}
${renderStack(renderApiKeysCard(props), renderAppearanceCard(props))}
${renderStack(renderPersonalCard(props))} ${renderPresetsCard(props)}
${renderStack(renderAppearanceCard(props))} ${renderStack(renderPersonalCard(props))}
${renderPresetsCard(props)}
</div>
${renderConnectionFooter(props)}