diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 77872eedadd..89eaf8c2e35 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -156,7 +156,7 @@ export function Session() { const sidebarVisible = createMemo(() => { if (session()?.parentID) return false if (sidebarOpen()) return true - if (sidebar() === "auto" && wide()) return true + if (sidebar() === "auto" && ((sync.data.config.tui as any)?.no_sidebar_auto || wide())) return true return false }) const showTimestamps = createMemo(() => timestamps() === "show") diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index a231a530072..d89d61b9810 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -928,6 +928,10 @@ export namespace Config { .enum(["auto", "stacked"]) .optional() .describe("Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column"), + no_sidebar_auto: z + .boolean() + .optional() + .describe("When true, 'auto' sidebar mode always shows the sidebar regardless of window width"), }) export const Server = z diff --git a/packages/opencode/test/config/config.test.ts b/packages/opencode/test/config/config.test.ts index 91b87f6498c..67de4ffd7a2 100644 --- a/packages/opencode/test/config/config.test.ts +++ b/packages/opencode/test/config/config.test.ts @@ -1602,6 +1602,29 @@ describe("deduplicatePlugins", () => { }) }) +test("loads tui.no_sidebar_auto config", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write( + path.join(dir, "opencode.jsonc"), + JSON.stringify({ + $schema: "https://opencode.ai/config.json", + tui: { + no_sidebar_auto: true, + }, + }), + ) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await Config.get() + expect(config.tui?.no_sidebar_auto).toBe(true) + }, + }) +}) + describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => { test("skips project config files when flag is set", async () => { const originalEnv = process.env["OPENCODE_DISABLE_PROJECT_CONFIG"] @@ -1713,7 +1736,7 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => { instructions: ["./CUSTOM.md"], }), ) - // Create the instruction file (should be skipped) + // Create instruction file (should be skipped) await Bun.write(path.join(dir, "CUSTOM.md"), "# Custom Instructions") }, }) @@ -1722,12 +1745,12 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => { directory: tmp.path, fn: async () => { // The relative instruction should be skipped without error - // We're mainly verifying this doesn't throw and the config loads + // We're mainly verifying this doesn't throw and config loads const config = await Config.get() expect(config).toBeDefined() // The instruction should have been skipped (warning logged) // We can't easily test the warning was logged, but we verify - // the relative path didn't cause an error + // relative path didn't cause an error }, }) } finally { @@ -1751,7 +1774,7 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => { try { await using configDirTmp = await tmpdir({ init: async (dir) => { - // Create config in the custom config dir + // Create config in custom config dir await Bun.write( path.join(dir, "opencode.json"), JSON.stringify({ diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index d72c37a28b5..19fea00f989 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1641,6 +1641,10 @@ export type Config = { * Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column */ diff_style?: "auto" | "stacked" + /** + * When true, 'auto' sidebar mode always shows the sidebar regardless of window width + */ + no_sidebar_auto?: boolean } server?: ServerConfig /**