import { Link } from "@tanstack/react-router" import { CalendarBlankIcon, ChartLineUpIcon, ChatCircleIcon, LightningIcon, PlusIcon, XIcon, } from "@phosphor-icons/react" import { IoLogoGithub, IoLogoSlack } from "react-icons/io5" import { SiLinear } from "react-icons/si" import type { ComponentType, SVGProps } from "react" import type { SessionUser } from "@/lib/api" import type { AgentSource, AgentThread } from "@/lib/agents/types" import { SidebarUserMenu } from "@/components/SidebarUserMenu" import { SidebarCollapseButton, SidebarFrame, useSidebarLayout, } from "@/components/sidebar-layout" import { groupThreads } from "@/lib/agents/api" import { useAgentThreads, useDeleteAgentThread } from "@/lib/agents/queries" import { cn } from "@/lib/utils" type SourceIcon = ComponentType> const SOURCE_META: Record = { dashboard: { icon: ChatCircleIcon, label: "Started from the dashboard" }, github: { icon: IoLogoGithub, label: "Triggered from GitHub" }, slack: { icon: IoLogoSlack, label: "Triggered from Slack" }, linear: { icon: SiLinear, label: "Triggered from Linear" }, schedule: { icon: CalendarBlankIcon, label: "Triggered from a schedule" }, } interface AgentsSidebarProps { user: SessionUser activeThreadId?: string } const NAV = [ { to: "/agents/automations", label: "Automations", icon: LightningIcon }, { to: "/my-settings", label: "Dashboard", icon: ChartLineUpIcon }, ] as const export function AgentsSidebar({ user, activeThreadId }: AgentsSidebarProps) { const threadsQuery = useAgentThreads() const threads = threadsQuery.data ?? [] const groups = groupThreads(threads) const layout = useSidebarLayout() return (
open-swe
New Agent
) } function ThreadGroup({ label, threads, activeThreadId, onNavigate, }: { label: string threads: Array activeThreadId?: string onNavigate?: () => void }) { if (threads.length === 0) return null return (
{label}
{threads.map((thread) => ( ))}
) } function ThreadRow({ thread, isActive, onNavigate, }: { thread: AgentThread isActive: boolean onNavigate?: () => void }) { const deleteThread = useDeleteAgentThread() const badge = thread.diffStats && thread.diffStats.additions > 0 ? `+${thread.diffStats.additions}` : null const isDeleting = deleteThread.isPending && deleteThread.variables === thread.id const onDelete = (e: React.MouseEvent) => { e.preventDefault() e.stopPropagation() if (isDeleting) return if (!window.confirm(`Delete "${thread.title}"? This cannot be undone.`)) return deleteThread.mutate(thread.id) } const source = thread.source && thread.source !== "dashboard" ? SOURCE_META[thread.source] : null const SourceIcon = source?.icon return ( {source && SourceIcon && ( {source.label} )} {thread.title} {badge && ( {badge} )} ) } export function AgentsShell({ user, activeThreadId, children, }: { user: SessionUser activeThreadId?: string children: React.ReactNode }) { return (
{children}
) }