From 3618aa5f07e2a134f5aae83b3c1b7fdb92763cb6 Mon Sep 17 00:00:00 2001 From: shenghui kevin Date: Sat, 21 Feb 2026 05:06:47 -0800 Subject: [PATCH 1/2] feat(config): add theme mode override option Allow users to manually set light/dark mode via the `theme_mode` config option, bypassing terminal auto-detection. This fixes issues with terminals (Zellij, JetBrains IDEs) that misreport the system theme. Co-Authored-By: Claude Opus 4.6 --- .../opencode/src/cli/cmd/tui/context/theme.tsx | 14 +++++++++++++- packages/opencode/src/config/config.ts | 6 ++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx index 465ed805ea17..eb9412e1e4f3 100644 --- a/packages/opencode/src/cli/cmd/tui/context/theme.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/theme.tsx @@ -282,9 +282,16 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ init: (props: { mode: "dark" | "light" }) => { const sync = useSync() const kv = useKV() + + function configMode(): "dark" | "light" | undefined { + const override = sync.data.config.theme_mode as "light" | "dark" | "system" | undefined + if (override === "light" || override === "dark") return override + return undefined + } + const [store, setStore] = createStore({ themes: DEFAULT_THEMES, - mode: kv.get("theme_mode", props.mode), + mode: configMode() ?? kv.get("theme_mode", props.mode), active: (sync.data.config.theme ?? kv.get("theme", "opencode")) as string, ready: false, }) @@ -294,6 +301,11 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ if (theme) setStore("active", theme) }) + createEffect(() => { + const override = configMode() + if (override) setStore("mode", override) + }) + function init() { resolveSystemTheme() getCustomThemes() diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index aad0fd76c4be..b7b495a46741 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -1018,6 +1018,12 @@ export namespace Config { .object({ $schema: z.string().optional().describe("JSON schema reference for configuration validation"), theme: z.string().optional().describe("Theme name to use for the interface"), + theme_mode: z + .enum(["light", "dark", "system"]) + .optional() + .describe( + "Override the detected terminal color scheme. Set to 'light' or 'dark' to force a mode, or 'system' to auto-detect from terminal.", + ), keybinds: Keybinds.optional().describe("Custom keybind configurations"), logLevel: Log.Level.optional().describe("Log level"), tui: TUI.optional().describe("TUI specific settings"), From 7e1fcb38c88f4008b3aa3287f807cae13a5adac0 Mon Sep 17 00:00:00 2001 From: shenghui kevin Date: Sat, 21 Feb 2026 05:24:00 -0800 Subject: [PATCH 2/2] fix: add theme_mode to SDK types and remove unnecessary cast The Config type in the SDK did not include the new theme_mode field, which would cause a typecheck failure. Added the field to both v1 and v2 SDK generated types and removed the `as` cast in theme.tsx since the type now properly includes the property. Co-Authored-By: Claude Opus 4.6 --- packages/opencode/src/cli/cmd/tui/context/theme.tsx | 2 +- packages/sdk/js/src/gen/types.gen.ts | 4 ++++ packages/sdk/js/src/v2/gen/types.gen.ts | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx index eb9412e1e4f3..6d9cd408c226 100644 --- a/packages/opencode/src/cli/cmd/tui/context/theme.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/theme.tsx @@ -284,7 +284,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ const kv = useKV() function configMode(): "dark" | "light" | undefined { - const override = sync.data.config.theme_mode as "light" | "dark" | "system" | undefined + const override = sync.data.config.theme_mode if (override === "light" || override === "dark") return override return undefined } diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index 8eefe5bfe985..a4b866ab1bff 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -1181,6 +1181,10 @@ export type Config = { * Theme name to use for the interface */ theme?: string + /** + * Override the detected terminal color scheme. Set to 'light' or 'dark' to force a mode, or 'system' to auto-detect from terminal. + */ + theme_mode?: "light" | "dark" | "system" keybinds?: KeybindsConfig /** * Log level diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 4050ef15738c..c16457196bba 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1676,6 +1676,10 @@ export type Config = { * Theme name to use for the interface */ theme?: string + /** + * Override the detected terminal color scheme. Set to 'light' or 'dark' to force a mode, or 'system' to auto-detect from terminal. + */ + theme_mode?: "light" | "dark" | "system" keybinds?: KeybindsConfig logLevel?: LogLevel /**