From c6ebc7ff7c8e2dcbc8d09406e764d31f80d40943 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Sat, 4 Apr 2026 19:25:37 -0400 Subject: [PATCH] fix(tui): only show org switch affordances when useful (#21054) --- packages/opencode/src/cli/cmd/tui/app.tsx | 30 +++++++++++-------- .../cli/cmd/tui/component/prompt/index.tsx | 9 +++++- packages/opencode/src/config/config.ts | 1 + packages/opencode/src/config/console-state.ts | 2 ++ .../src/server/routes/experimental.ts | 6 +++- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 8ce7382929..6b2633c371 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -630,19 +630,23 @@ function App(props: { onSnapshot?: () => Promise }) { }, category: "Provider", }, - { - title: "Switch org", - value: "console.org.switch", - suggested: Boolean(sync.data.console_state.activeOrgName), - slash: { - name: "org", - aliases: ["orgs", "switch-org"], - }, - onSelect: () => { - dialog.replace(() => ) - }, - category: "Provider", - }, + ...(sync.data.console_state.switchableOrgCount > 1 + ? [ + { + title: "Switch org", + value: "console.org.switch", + suggested: Boolean(sync.data.console_state.activeOrgName), + slash: { + name: "org", + aliases: ["orgs", "switch-org"], + }, + onSelect: () => { + dialog.replace(() => ) + }, + category: "Provider", + }, + ] + : []), { title: "View status", keybind: "status_view", diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 55bf1d5630..5123cea567 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -96,6 +96,7 @@ export function Prompt(props: PromptProps) { const shell = createMemo(() => props.placeholders?.shell ?? []) const [auto, setAuto] = createSignal() const activeOrgName = createMemo(() => sync.data.console_state.activeOrgName) + const canSwitchOrgs = createMemo(() => sync.data.console_state.switchableOrgCount > 1) const currentProviderLabel = createMemo(() => { const current = local.model.current() const provider = local.model.parsed().provider @@ -1118,7 +1119,13 @@ export function Prompt(props: PromptProps) { {props.right} - command.trigger("console.org.switch")}> + { + if (!canSwitchOrgs()) return + command.trigger("console.org.switch") + }} + > {`${CONSOLE_MANAGED_ICON} ${activeOrgName()}`} diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 83e677bcb7..b11ae83192 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -1469,6 +1469,7 @@ export namespace Config { consoleState: { consoleManagedProviders: Array.from(consoleManagedProviders), activeOrgName, + switchableOrgCount: 0, }, } }) diff --git a/packages/opencode/src/config/console-state.ts b/packages/opencode/src/config/console-state.ts index a5d1f6d269..cf96a4e305 100644 --- a/packages/opencode/src/config/console-state.ts +++ b/packages/opencode/src/config/console-state.ts @@ -3,6 +3,7 @@ import z from "zod" export const ConsoleState = z.object({ consoleManagedProviders: z.array(z.string()), activeOrgName: z.string().optional(), + switchableOrgCount: z.number().int().nonnegative(), }) export type ConsoleState = z.infer @@ -10,4 +11,5 @@ export type ConsoleState = z.infer export const emptyConsoleState: ConsoleState = { consoleManagedProviders: [], activeOrgName: undefined, + switchableOrgCount: 0, } diff --git a/packages/opencode/src/server/routes/experimental.ts b/packages/opencode/src/server/routes/experimental.ts index a4b1f4d084..c673393d0e 100644 --- a/packages/opencode/src/server/routes/experimental.ts +++ b/packages/opencode/src/server/routes/experimental.ts @@ -54,7 +54,11 @@ export const ExperimentalRoutes = lazy(() => }, }), async (c) => { - return c.json(await Config.getConsoleState()) + const [consoleState, groups] = await Promise.all([Config.getConsoleState(), Account.orgsByAccount()]) + return c.json({ + ...consoleState, + switchableOrgCount: groups.reduce((count, group) => count + group.orgs.length, 0), + }) }, ) .get(