From bd4557291bd914a8b8542e85aea032cf45154bdd Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Fri, 7 Aug 2026 20:03:34 +1000 Subject: [PATCH] fix(app): align settings with v2 APIs --- .../project-settings-extensions.tsx | 10 +++--- .../src/components/settings-v2/appearance.tsx | 6 ++-- .../src/components/settings-v2/extensions.tsx | 18 +++++----- .../src/components/settings-v2/providers.tsx | 35 +++++-------------- packages/app/src/i18n/parity.test.ts | 5 +++ 5 files changed, 29 insertions(+), 45 deletions(-) diff --git a/packages/app/src/components/project-settings-extensions.tsx b/packages/app/src/components/project-settings-extensions.tsx index 9505c71d6a..0e42d66516 100644 --- a/packages/app/src/components/project-settings-extensions.tsx +++ b/packages/app/src/components/project-settings-extensions.tsx @@ -8,7 +8,7 @@ import { useSDK } from "@/context/sdk" import { useServerSDK } from "@/context/server-sdk" import { useServerSync } from "@/context/server-sync" import { useSync } from "@/context/sync" -import { ExternalLink } from "./external-link" +import { Link } from "./link" type SkillItem = { name: string @@ -111,9 +111,7 @@ export const ProjectSettingsExtensions: Component = () => { const [serverSkills] = createResource( serverSDK, (sdk): Promise => - sdk.api.skill - .list() - .then((result) => result.data.map((item) => ({ name: item.name, location: item.location }))), + sdk.api.skill.list().then((result) => result.data.map((item) => ({ name: item.name, location: item.location }))), { initialValue: [] }, ) const [directorySkills] = createResource( @@ -200,9 +198,9 @@ export const ProjectSettingsExtensions: Component = () => {
{language.t("project.settings.extensions.added")} - + {language.t("settings.extensions.addSkills")} - +
0}> {skillRows(projectSkills())} diff --git a/packages/app/src/components/settings-v2/appearance.tsx b/packages/app/src/components/settings-v2/appearance.tsx index beb72b0b85..c9a937081e 100644 --- a/packages/app/src/components/settings-v2/appearance.tsx +++ b/packages/app/src/components/settings-v2/appearance.tsx @@ -2,7 +2,7 @@ import { Component, createMemo } from "solid-js" import { SelectV2 } from "@opencode-ai/ui/v2/select-v2" import { TextInputV2 } from "@opencode-ai/ui/v2/text-input-v2" import { useLanguage } from "@/context/language" -import { ExternalLink } from "../external-link" +import { Link } from "../link" import { SettingsListV2 } from "./parts/list" import { SettingsRowV2 } from "./parts/row" import { createAppearanceSettingsController, type AppearanceSettingsController } from "./general-controllers" @@ -104,9 +104,9 @@ export const SettingsAppearanceV2: Component = () => { description={ <> {language.t("settings.general.row.theme.description")}{" "} - + {language.t("common.learnMore")} - + } > diff --git a/packages/app/src/components/settings-v2/extensions.tsx b/packages/app/src/components/settings-v2/extensions.tsx index bbe4e26453..efb0909362 100644 --- a/packages/app/src/components/settings-v2/extensions.tsx +++ b/packages/app/src/components/settings-v2/extensions.tsx @@ -5,7 +5,7 @@ import { TabsV2 } from "@opencode-ai/ui/v2/tabs-v2" import { useLanguage } from "@/context/language" import { useServerSDK } from "@/context/server-sdk" import { useServerSync } from "@/context/server-sync" -import { ExternalLink } from "../external-link" +import { Link } from "../link" import { InlineServerSelect } from "./parts/server-select" import "./settings-v2.css" @@ -26,14 +26,14 @@ export const SettingsExtensionsV2: Component = () => { const configMcp = serverSync().data.config.mcp ?? {} return Object.entries(configMcp).map(([name, config]) => ({ name, - enabled: config.enabled !== false, + enabled: typeof config !== "object" || config === null || !("enabled" in config) || config.enabled !== false, })) }) const handleMcpToggle = (item: McpRowItem, checked: boolean) => { const before = serverSync().data.config.mcp ?? {} const config = before[item.name] - if (!config) return + if (typeof config !== "object" || config === null) return const next = { ...before, [item.name]: { ...config, enabled: checked } } serverSync().set("config", "mcp", next) void serverSync() @@ -49,11 +49,9 @@ export const SettingsExtensionsV2: Component = () => { }) }) - const [skills] = createResource( - serverSdk, - (sdk) => sdk.api.skill.list().then((result) => result.data), - { initialValue: [] }, - ) + const [skills] = createResource(serverSdk, (sdk) => sdk.api.skill.list().then((result) => result.data), { + initialValue: [], + }) return ( <> @@ -130,12 +128,12 @@ export const SettingsExtensionsV2: Component = () => { {language.t("settings.extensions.availableAll")} - {language.t("settings.extensions.addSkills")} - +
diff --git a/packages/app/src/components/settings-v2/providers.tsx b/packages/app/src/components/settings-v2/providers.tsx index b294a5c0e0..35a1588aad 100644 --- a/packages/app/src/components/settings-v2/providers.tsx +++ b/packages/app/src/components/settings-v2/providers.tsx @@ -52,9 +52,15 @@ export const SettingsProvidersV2: Component<{ } const connected = createMemo(() => { - return providers - .connected() - .filter((p) => p.id !== "opencode" || Object.values(p.models).find((m) => m.cost?.input)) + return providers.connected().filter( + (provider) => + provider.id !== "opencode" || + Object.values(provider.models).some((model) => { + if (typeof model !== "object" || model === null || !("cost" in model)) return false + const cost = model.cost + return typeof cost === "object" && cost !== null && "input" in cost + }), + ) }) const popular = createMemo(() => { @@ -98,29 +104,6 @@ export const SettingsProvidersV2: Component<{ return true } - const disableProvider = async (providerID: string, name: string) => { - return - const before = serverSync().data.config.disabled_providers ?? [] - const next = before.includes(providerID) ? before : [...before, providerID] - sync.set("config", "disabled_providers", next) - - await sync - .updateConfig({ disabled_providers: next }) - .then(() => { - showToast({ - variant: "success", - icon: "circle-check", - title: language.t("provider.disconnect.toast.disconnected.title", { provider: name }), - description: language.t("provider.disconnect.toast.disconnected.description", { provider: name }), - }) - }) - .catch((err: unknown) => { - sync.set("config", "disabled_providers", before) - const message = err instanceof Error ? err.message : String(err) - showToast({ title: language.t("common.requestFailed"), description: message }) - }) - } - const disconnect = async (providerID: string, name: string) => { const location = props.directory() ? { directory: props.directory() } : undefined await serverSdk() diff --git a/packages/app/src/i18n/parity.test.ts b/packages/app/src/i18n/parity.test.ts index afc1574e9f..50da0bb37d 100644 --- a/packages/app/src/i18n/parity.test.ts +++ b/packages/app/src/i18n/parity.test.ts @@ -75,6 +75,11 @@ const pluralCategories = new Map( ), ) const appFallbackKeys = new Set([ + "dialog.provider.custom.label", + "dialog.model.unpaid.viewMoreProviders", + "session.header.reveal.finder", + "session.header.reveal.fileExplorer", + "session.header.reveal.containingFolder", "command.session.export", "command.session.export.description", "context.export.session",