diff --git a/src/renderer/src/components/right-sidebar/index.tsx b/src/renderer/src/components/right-sidebar/index.tsx index d6f4b64c725..6a3a6ba1fa1 100644 --- a/src/renderer/src/components/right-sidebar/index.tsx +++ b/src/renderer/src/components/right-sidebar/index.tsx @@ -124,12 +124,11 @@ function RightSidebarInner(): React.JSX.Element { const checksStatus = useAppStore(getActiveChecksStatus) const activityBarPosition = useAppStore((s) => s.activityBarPosition) const setActivityBarPosition = useAppStore((s) => s.setActivityBarPosition) - // Why: the bottom-docked agent dashboard is opt-out via Settings → Agents, - // AND gated behind the experimental opt-in setting. Users who prefer a - // quieter sidebar can hide the panel without losing any in-terminal agent - // status — the per-tab status indicators remain. While settings are still - // loading, render the panel so it doesn't flash in once settings arrive. - const showAgentDashboard = useAppStore((s) => s.settings?.showAgentDashboard !== false) + // Why: the bottom-docked agent dashboard is opt-in via Settings → Agents + // AND gated behind the experimental opt-in setting. Undefined/missing + // settings (first hydrate, never-toggled) must read as off so the panel + // doesn't flash in before settings load. + const showAgentDashboard = useAppStore((s) => s.settings?.showAgentDashboard === true) const dashboardExperimentEnabled = useAppStore( (s) => s.settings?.experimentalAgentDashboard === true ) diff --git a/src/renderer/src/components/settings/AgentsPane.tsx b/src/renderer/src/components/settings/AgentsPane.tsx index 843c586e39d..1457595f0a2 100644 --- a/src/renderer/src/components/settings/AgentsPane.tsx +++ b/src/renderer/src/components/settings/AgentsPane.tsx @@ -246,11 +246,10 @@ export function AgentsPane({ settings, updateSettings }: AgentsPaneProps): React defaultAgent === null || (defaultAgent !== 'blank' && !detectedIds?.has(defaultAgent)) const isBlankDefault = defaultAgent === 'blank' - // Why: match right-sidebar's `s.settings?.showAgentDashboard !== false` read. - // Persisted settings from older versions may be missing this field — treating - // `undefined` as "on" here keeps the toggle's displayed state in sync with - // the sidebar's actual rendering, so the UI never contradicts itself. - const showDashboard = settings.showAgentDashboard !== false + // Why: match right-sidebar's `s.settings?.showAgentDashboard === true` read + // so the toggle's displayed state stays in sync with the sidebar's actual + // rendering. Undefined reads as off (opt-in). + const showDashboard = settings.showAgentDashboard === true return (
diff --git a/src/shared/types.ts b/src/shared/types.ts index d5ff5d01271..e5cc98f5341 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -920,14 +920,9 @@ export type GlobalSettings = { /** Whether to show the live agent activity count badge in the titlebar. */ showTitlebarAgentActivity: boolean /** Whether to show the Agent Dashboard panel at the bottom of the right sidebar. - * Why: optional because readers use the `settings?.showAgentDashboard !== false` - * idiom (right-sidebar/index.tsx, AgentsPane.tsx) which presumes the field may - * be undefined — e.g. on first hydrate before main-process defaults apply, or - * when migrating settings persisted before this field existed. A required - * `boolean` here would make those readers' fallback branches dead-on-paper - * while still being reached at runtime, which is exactly the kind of type - * hack that drifts silently. Aligning the declaration with reader intent - * keeps the contract honest. */ + * Why: optional because renderer readers use `settings?.showAgentDashboard === true` + * — the field may be undefined on first hydrate before main-process defaults + * apply, and undefined must read as off (opt-in). */ showAgentDashboard?: boolean /** Why: the Tasks sidebar label can be kept cleaner for users who do not * actively use the GitHub/Linear integrations behind it. */