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 5f47562d2e3..e4f2b28c9c8 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -152,7 +152,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 020e626cba8..915440799c1 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -810,6 +810,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 decd18446c1..63094db2827 100644 --- a/packages/opencode/test/config/config.test.ts +++ b/packages/opencode/test/config/config.test.ts @@ -1413,6 +1413,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"] @@ -1524,7 +1547,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") }, }) @@ -1533,12 +1556,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 { @@ -1562,7 +1585,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({