From 5dd4fb05c610afeeae5584fdce03f22db0d829be Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Wed, 13 May 2026 20:06:33 -0500 Subject: [PATCH] refactor(desktop): make /agents subagent-only, drop sidebar + dead sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Activity rail and History stub were both noise. Strip the split layout, sidebar, route enum, and the rail/stub helpers — the overlay is now just the spawn tree, centered in a max-w-3xl column so it stops claiming the whole screen for one section's worth of content. --- apps/desktop/src/app/agents/index.tsx | 144 +++----------------------- 1 file changed, 14 insertions(+), 130 deletions(-) diff --git a/apps/desktop/src/app/agents/index.tsx b/apps/desktop/src/app/agents/index.tsx index 176d7035c53..cc5afa17f42 100644 --- a/apps/desktop/src/app/agents/index.tsx +++ b/apps/desktop/src/app/agents/index.tsx @@ -5,21 +5,10 @@ import { useElapsedSeconds } from '@/components/chat/activity-timer' import { ActivityTimerText } from '@/components/chat/activity-timer-text' import { BrailleSpinner } from '@/components/ui/braille-spinner' import { FadeText } from '@/components/ui/fade-text' -import { - Activity, - AlertCircle, - CheckCircle2, - Layers3, - Loader2, - type LucideIcon, - RefreshCw, - Sparkles -} from '@/lib/icons' +import { AlertCircle, CheckCircle2, Sparkles } from '@/lib/icons' import { useEnterAnimation } from '@/lib/use-enter-animation' import { cn } from '@/lib/utils' -import { $desktopActionTasks, buildRailTasks, type RailTask, type RailTaskStatus } from '@/store/activity' -import { $previewServerRestart } from '@/store/preview' -import { $activeSessionId, $sessions, $workingSessionIds } from '@/store/session' +import { $activeSessionId } from '@/store/session' import { $subagentsBySession, buildSubagentTree, @@ -28,39 +17,8 @@ import { type SubagentStreamEntry } from '@/store/subagents' -import { useRouteEnumParam } from '../hooks/use-route-enum-param' -import { OverlayMain, OverlayNavItem, OverlaySidebar, OverlaySplitLayout } from '../overlays/overlay-split-layout' import { OverlayView } from '../overlays/overlay-view' -type AgentsSection = 'tree' | 'activity' | 'history' - -interface SectionDef { - description: string - icon: LucideIcon - id: AgentsSection - label: string -} - -const SECTIONS: readonly SectionDef[] = [ - { description: 'Live subagent spawn tree for the current turn', icon: Layers3, id: 'tree', label: 'Spawn tree' }, - { description: 'Background work across sessions and the desktop', icon: Activity, id: 'activity', label: 'Activity' }, - { description: 'Past spawn snapshots, replay, and diff', icon: RefreshCw, id: 'history', label: 'History' } -] - -const SECTION_IDS = SECTIONS.map(s => s.id) as readonly AgentsSection[] - -const RAIL_TONE: Record = { - error: 'text-destructive', - running: 'text-foreground', - success: 'text-emerald-500' -} - -const RAIL_ICON: Record = { - error: AlertCircle, - running: Loader2, - success: Sparkles -} - // Mirrors statusGlyph() in tool-fallback.tsx so subagent rows speak the // same visual vocabulary as the chat tool blocks. function statusGlyph(status: SubagentStatus): ReactNode { @@ -114,27 +72,13 @@ function streamGlyph(entry: SubagentStreamEntry): ReactNode { } interface AgentsViewProps { - initialSection?: AgentsSection onClose: () => void } -export function AgentsView({ initialSection = 'tree', onClose }: AgentsViewProps) { - const [section, setSection] = useRouteEnumParam('section', SECTION_IDS, initialSection) - +export function AgentsView({ onClose }: AgentsViewProps) { const activeSessionId = useStore($activeSessionId) - const sessions = useStore($sessions) - const workingSessionIds = useStore($workingSessionIds) - const previewRestart = useStore($previewServerRestart) - const desktopActionTasks = useStore($desktopActionTasks) const subagentsBySession = useStore($subagentsBySession) - const activityTasks = useMemo( - () => buildRailTasks(workingSessionIds, sessions, previewRestart, desktopActionTasks), - [desktopActionTasks, previewRestart, sessions, workingSessionIds] - ) - - const active = SECTIONS.find(s => s.id === section) ?? SECTIONS[0]! - const activeSubagents = useMemo( () => (activeSessionId ? (subagentsBySession[activeSessionId] ?? []) : []), [activeSessionId, subagentsBySession] @@ -143,35 +87,17 @@ export function AgentsView({ initialSection = 'tree', onClose }: AgentsViewProps const tree = useMemo(() => buildSubagentTree(activeSubagents), [activeSubagents]) return ( - - - - {SECTIONS.map(s => ( - setSection(s.id)} - /> - ))} - - - -
-

{active.label}

-

{active.description}

-
- - {section === 'tree' ? ( - - ) : section === 'activity' ? ( - - ) : ( - - )} -
-
+ +
+

Spawn tree

+

Live subagent activity for the current turn.

+
+
) } @@ -449,45 +375,3 @@ function SubagentRow({ node, depth = 0, nowMs }: { node: SubagentNode; depth?: n ) } -function ActivityList({ tasks }: { tasks: readonly RailTask[] }) { - if (tasks.length === 0) { - return ( -

- No background activity. Long-running tools, preview restarts, and parallel sessions surface here. -

- ) - } - - return ( -
- {tasks.map(task => { - const Icon = RAIL_ICON[task.status] - - return ( -
- -
-
{task.label}
- {task.detail ?
{task.detail}
: null} -
-
- ) - })} -
- ) -} - -function SectionStub({ label }: { label: string }) { - return ( -
- -

{label} — coming soon

-
- ) -}