fix(desktop): move power-user views out of sidebar

Keep Cron and Profiles available through lower-prominence chrome entry points so the workspace sidebar stays focused on core chat navigation.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Austin Pickett
2026-05-13 12:45:48 -04:00
co-authored by Cursor
parent 30ba7bcd5a
commit 927e982b23
5 changed files with 70 additions and 21 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ export function AppShell({
// between the pane-tool cluster and the system cluster so they don't sit
// flush against each other. Modeled as N gaps (N - 1 inner + 1 trailing)
// to keep the formula generic for any pane-tool count.
const SYSTEM_TOOL_COUNT = 3
const SYSTEM_TOOL_COUNT = 4
const paneToolCount = titlebarTools?.filter(tool => !tool.hidden).length ?? 0
const systemToolsWidth = `calc(${SYSTEM_TOOL_COUNT} * (var(--titlebar-control-size) + 0.25rem))`
@@ -4,7 +4,7 @@ import { useCallback, useMemo, useState } from 'react'
import type { CommandCenterSection } from '@/app/command-center'
import { GatewayMenuPanel } from '@/app/shell/gateway-menu-panel'
import { restartGateway } from '@/hermes'
import { Activity, AlertCircle, Command, Cpu, FolderOpen, GitBranch, Hash, Loader2, Sparkles } from '@/lib/icons'
import { Activity, AlertCircle, Clock, Command, Cpu, FolderOpen, GitBranch, Hash, Loader2, Sparkles } from '@/lib/icons'
import { compactPath, contextBarLabel, LiveDuration, usageContextLabel } from '@/lib/statusbar'
import { cn } from '@/lib/utils'
import { $desktopActionTasks } from '@/store/activity'
@@ -25,6 +25,7 @@ import {
import { $desktopVersion, $updateApply, $updateStatus, setUpdateOverlayOpen } from '@/store/updates'
import type { StatusResponse } from '@/types/hermes'
import { CRON_ROUTE } from '../../routes'
import type { StatusbarItem } from '../statusbar-controls'
interface StatusbarItemsOptions {
@@ -203,6 +204,14 @@ export function useStatusbarItems({
onSelect: openAgents,
title: agentsOpen ? 'Close agents' : 'Open agents',
variant: 'action'
},
{
icon: <Clock className="size-3" />,
id: 'cron',
label: 'Cron',
title: 'Open cron jobs',
to: CRON_ROUTE,
variant: 'action'
}
],
[
@@ -2,12 +2,22 @@ import { useStore } from '@nanostores/react'
import type { ComponentProps, ReactNode } from 'react'
import { useNavigate } from 'react-router-dom'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
import { triggerHaptic } from '@/lib/haptics'
import { FolderOpen, NotebookTabs, Settings, Volume2, VolumeX } from '@/lib/icons'
import { FolderOpen, NotebookTabs, Settings, Users, Volume2, VolumeX } from '@/lib/icons'
import { cn } from '@/lib/utils'
import { $hapticsMuted, toggleHapticsMuted } from '@/store/haptics'
import { $fileBrowserOpen, $sidebarOpen, toggleFileBrowserOpen, toggleSidebarOpen } from '@/store/layout'
import { PROFILES_ROUTE } from '../routes'
import { titlebarButtonClass } from './titlebar'
export interface TitlebarTool {
@@ -95,6 +105,8 @@ export function TitlebarControls({ leftTools = [], tools = [], onOpenSettings }:
]
const visibleSystemTools = systemTools.filter(tool => !tool.hidden)
const settingsTool = visibleSystemTools.find(tool => tool.id === 'settings')
const visibleSystemToolsBeforeSettings = visibleSystemTools.filter(tool => tool.id !== 'settings')
const visiblePaneTools = tools.filter(tool => !tool.hidden)
return (
@@ -133,14 +145,55 @@ export function TitlebarControls({ leftTools = [], tools = [], onOpenSettings }:
aria-label="App controls"
className="fixed right-(--titlebar-tools-right) top-(--titlebar-controls-top) z-70 flex flex-row items-center justify-end gap-x-1 pointer-events-auto select-none [-webkit-app-region:no-drag]"
>
{visibleSystemTools.map(tool => (
{visibleSystemToolsBeforeSettings.map(tool => (
<TitlebarToolButton key={tool.id} navigate={navigate} tool={tool} />
))}
<ProfilesMenuButton navigate={navigate} />
{settingsTool && <TitlebarToolButton navigate={navigate} tool={settingsTool} />}
</div>
</>
)
}
function ProfilesMenuButton({ navigate }: { navigate: ReturnType<typeof useNavigate> }) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button
aria-label="Profiles"
className={cn(
titlebarButtonClass,
'grid place-items-center bg-transparent select-none [&_svg]:size-4'
)}
onPointerDown={event => event.stopPropagation()}
title="Profiles"
type="button"
>
<Users />
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-64" sideOffset={8}>
<DropdownMenuLabel>
<div className="text-sm font-medium text-foreground">Profiles</div>
<div className="mt-1 text-xs font-normal leading-4 text-muted-foreground">
Advanced Hermes environments for separate personas, config, skills, and SOUL.md.
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem
onSelect={() => {
triggerHaptic('open')
navigate(PROFILES_ROUTE)
}}
>
<Users className="size-4" />
<span>Manage profiles</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}
function TitlebarToolButton({ navigate, tool }: { navigate: ReturnType<typeof useNavigate>; tool: TitlebarTool }) {
const className = cn(
titlebarButtonClass,