MailDebuggerPanel.tsx32.6 KBView on GitHub
import {
  GripHorizontal,
  Inbox,
  Mail,
  MessageSquare,
  Network,
  Database,
  RefreshCw,
  TestTube,
  Users,
  X,
  History,
  Briefcase,
  Calendar,
  Layout,
  Bot,
  Bug,
  Palette,
  Video,
  FileText,
  Layers,
  Snowflake,
  MessagesSquare,
} from 'lucide-react';
import { useSelectedThreadData, useSelectedThreadId, useCedarStore } from '@/modules/store';
import { selectMergedFeed } from '@/modules/inbox/store/inboxSlice';
import { CRMTab } from '@/modules/cedar-os/src/cedar-os-components/debugger/CRMTab';
import { useAgentExecutionsStore } from '@/modules/aop/store/agentExecutionsSlice';
import { AnimatePresence, motion, useDragControls } from 'motion/react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/ui/tabs';
import { useSession } from '@/modules/auth/utils/auth-client';
import { selectChatThreadId } from '@/modules/ux/uxSlice';
import { AgentExecutionsDebuggerTab } from './AgentExecutionsDebuggerTab';
import { useAOPs } from '@/modules/aop/hooks/use-aops';
import { CurrentThreadDebuggerTab } from './CurrentThreadDebuggerTab';
import { ConversationsDebuggerTab } from './ConversationsDebuggerTab';
import { AgentCanvasDebuggerTab } from './AgentCanvasDebuggerTab';
import Container from '@/containers/Container';
import { CalendarDebuggerTab } from './CalendarDebuggerTab';
import { cn } from '@/styles/stylingUtils';
import { ThreadsDebuggerTab } from './ThreadsDebuggerTab';
import { InboxDebuggerTab } from './InboxDebuggerTab';
import { TestDebuggerTab } from './TestDebuggerTab';
import { AOPDebuggerTab } from './AOPDebuggerTab';
import { UXDebuggerTab } from './UXDebuggerTab';
import { NetworkTab } from '@/modules/cedar-os/src/cedar-os-components/debugger/NetworkTab';
import { MessagesTab } from '@/modules/cedar-os/src/cedar-os-components/debugger/MessagesTab';
import { AgentContextDebuggerTab } from './AgentContextDebuggerTab';
import { MeetingsDebuggerTab } from './MeetingsDebuggerTab';
import { ConversationDocsDebuggerTab } from './ConversationDocsDebuggerTab';
import { TimelineDebuggerTab } from './TimelineDebuggerTab';
import { FreezesDebuggerTab } from './FreezesDebuggerTab';
import { setEnabled as setDeepDebuggerEnabled, isEnabled as isDeepDebuggerEnabled } from '@/modules/debugger/deepDebugger/buffer';
import { ChatThreadsDebuggerTab } from './ChatThreadsDebuggerTab';
import type {
  DebugLogEntry,
  Message as DebuggerMessage,
} from '@/modules/cedar-os/src/cedar-os-components/debugger/types';

interface MailDebuggerPanelProps {
  /** Optional class name */
  className?: string;
}

export const MailDebuggerPanel: React.FC<MailDebuggerPanelProps> = ({ className }) => {
  const { data: session } = useSession();
  const [isExpanded, setIsExpanded] = useState(false);
  const [activeTab, setActiveTab] = useState('timeline');
  const [copiedId, setCopiedId] = useState<string | null>(null);

  // Get mail data from stores/hooks using new Zustand architecture
  const currentThreadId = useSelectedThreadId();
  const threadData = useSelectedThreadData();
  const allConversationsMap = useCedarStore((state) => state.conversations);
  const activeConversationId = useCedarStore((state) => state.activeConversationId);
  const allThreadDataMap = useCedarStore((state) => state.threadData);
  const allAgentExecutions = useAgentExecutionsStore((state) => state.executions);
  const currentConversationList = useCedarStore((state) => state.currentConversationList);

  // Panel dimensions state - hardcoded defaults
  const [panelWidth, setPanelWidth] = useState(600);
  const [panelHeight, setPanelHeight] = useState(450);

  // Hardcoded minimum and maximum sizes
  const minWidth = 400;
  const minHeight = 300;
  const calculatedMaxWidth = typeof window !== 'undefined' ? window.innerWidth * 0.8 : 1000;
  const calculatedMaxHeight = typeof window !== 'undefined' ? window.innerHeight * 0.8 : 800;

  // Resize state
  const [isResizing, setIsResizing] = useState<
    null | 'width' | 'height' | 'both' | 'bottom-left' | 'bottom-right'
  >(null);
  const dragStartX = useRef(0);
  const dragStartY = useRef(0);
  const dragStartWidth = useRef(0);
  const dragStartHeight = useRef(0);

  // Drag controls for both collapsed and expanded states
  const dragControls = useDragControls();
  const constraintsRef = useRef<HTMLDivElement>(null);

  // Get conversation data
  const currentConversationId = activeConversationId;
  const allConversations = allConversationsMap;
  const conversationsCount = Object.keys(allConversations).length;

  // Get threads from Zustand store (new architecture)
  const threadsCount = Object.keys(allThreadDataMap).length;
  const inboxItemsCount = useCedarStore(selectMergedFeed).items.length;
  const agentExecutionsCount = Object.keys(allAgentExecutions).length;

  // Get AOP state
  const { data: aopsData } = useAOPs();
  const aopsCount = aopsData?.aops?.length ?? 0;

  // Get CRM state
  const crmColumns = useCedarStore((state) => state.columns);
  const crmColumnsCount = Object.keys(crmColumns).length;

  // Get Calendar state
  const calendars = useCedarStore((state) => state.calendars);
  const calendarEvents = useCedarStore((state) => state.calendarEvents);
  const selectedCalendarEventId = useCedarStore((state) => state.selectedCalendarEventId);
  const calendarEventToConversation = useCedarStore((state) => state.calendarEventToConversation);
  const calendarsCount = calendars.length;
  const calendarEventsCount = calendarEvents.length;
  // Get UX state
  const sidePanelMode = useCedarStore((state) => state.sidePanelMode);
  const navigation = useCedarStore((state) => state.navigation);
  const chatThreadId = useCedarStore(selectChatThreadId);
  const chatThreadsCount = useCedarStore((state) => Object.keys(state.threadMap).length);
  const activeCanvasId = useCedarStore((state) => state.activeCanvasId);
  const isGlobalCanvasOpen = useCedarStore((state) => state.isGlobalCanvasOpen);
  const activeView = useCedarStore((state) => state.getActiveView());
  const commandStack = useCedarStore((state) => state.commandStack);
  const commandModalItemId = useCedarStore((state) => state.commandModalItemId);

  // Get file-system document state (single source of truth — agenda docs live
  // here too, mirrored via `setDocument` from the agenda hydration path).
  const documents = useCedarStore((state) => state.documents);
  const documentsCount = Object.keys(documents).length;

  // Get document save log state
  const docSaveEvents = useCedarStore((state) => state.docSaveEvents);
  const docSaveErrorCount = docSaveEvents.filter((e) => e.event.type === 'flush-error').length;

  // Get Canvas state counts (from canvasSlice, active canvas)
  const activeCanvas = useCedarStore((state) =>
    state.activeCanvasId ? state.canvasesById[state.activeCanvasId] : undefined,
  );
  const agentCanvasDataCount = Object.keys(activeCanvas?.data?.conversationEntries ?? {}).length;
  const pendingDraftsCount = Object.values(activeCanvas?.data?.conversationEntries ?? {}).filter(
    (e) => e.pendingDraft?.reviewStatus === 'pending',
  ).length;

  // Get debug state (merged from cedar-os DebuggerPanel)
  const agentConnectionLogs = useCedarStore(
    (state) => state.agentConnectionLogs,
  ) as DebugLogEntry[];
  const debugMessages = useCedarStore((state) => state.messages) as DebuggerMessage[];

  // Resize handlers
  const handleMouseMove = useCallback(
    (e: MouseEvent) => {
      if (!isResizing) return;

      let newWidth = panelWidth;
      let newHeight = panelHeight;

      if (
        isResizing === 'width' ||
        isResizing === 'both' ||
        isResizing === 'bottom-left' ||
        isResizing === 'bottom-right'
      ) {
        let deltaX = e.clientX - dragStartX.current;

        // For bottom-left corner, invert the deltaX since dragging left should increase width
        if (isResizing === 'bottom-left') {
          deltaX = -deltaX;
        }

        newWidth = Math.max(
          minWidth,
          Math.min(calculatedMaxWidth, dragStartWidth.current + deltaX),
        );
        setPanelWidth(newWidth);
      }

      if (
        isResizing === 'height' ||
        isResizing === 'both' ||
        isResizing === 'bottom-left' ||
        isResizing === 'bottom-right'
      ) {
        // For bottom corners, dragging down increases height
        const deltaY = e.clientY - dragStartY.current;
        newHeight = Math.max(
          minHeight,
          Math.min(calculatedMaxHeight, dragStartHeight.current + deltaY),
        );
        setPanelHeight(newHeight);
      }
    },
    [
      isResizing,
      minWidth,
      minHeight,
      calculatedMaxWidth,
      calculatedMaxHeight,
      panelWidth,
      panelHeight,
    ],
  );

  const handleMouseUp = useCallback(() => {
    setIsResizing(null);
    if (typeof document !== 'undefined') {
      document.body.style.userSelect = '';
      document.body.style.webkitUserSelect = '';
    }
  }, []);

  useEffect(() => {
    if (isResizing) {
      if (typeof document !== 'undefined') {
        document.addEventListener('mousemove', handleMouseMove);
        document.addEventListener('mouseup', handleMouseUp);
        document.body.style.userSelect = 'none';
        document.body.style.webkitUserSelect = 'none';
      }
    }
    return () => {
      if (typeof document !== 'undefined') {
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
      }
    };
  }, [isResizing, handleMouseMove, handleMouseUp]);

  const startResize = (
    direction: 'width' | 'height' | 'both' | 'bottom-left' | 'bottom-right',
    e: React.MouseEvent,
  ) => {
    e.preventDefault();
    e.stopPropagation(); // Prevent drag from interfering
    setIsResizing(direction);
    dragStartX.current = e.clientX;
    dragStartY.current = e.clientY;
    dragStartWidth.current = panelWidth;
    dragStartHeight.current = panelHeight;
  };

  const handleCopy = (text: string, id: string) => {
    navigator.clipboard.writeText(text);
    setCopiedId(id);
    setTimeout(() => setCopiedId(null), 2000);
  };

  const handleRefresh = () => {
    // Force refresh of current data
    window.location.reload();
  };

  // Calculate proper panel position when expanding
  const getExpandedPanelPosition = () => {
    if (typeof window === 'undefined') {
      return { x: 0, y: 0 };
    }

    const windowWidth = window.innerWidth;
    const windowHeight = window.innerHeight;
    const margin = 20;

    const x = windowWidth - panelWidth - margin;
    const y = windowHeight - panelHeight - margin;

    return { x, y };
  };

  const expandedPosition = getExpandedPanelPosition();

  // Show debugger panel in development OR for @cedarcopilot.com email addresses
  const shouldShowDebugger =
    process.env.NODE_ENV === 'development' || session?.user?.email?.endsWith('@cedarcopilot.com');

  // Enable deep-debugger capture for cedarcopilot users in prod (dev already enables it at module load).
  useEffect(() => {
    if (shouldShowDebugger && !isDeepDebuggerEnabled()) {
      setDeepDebuggerEnabled(true);
    }
  }, [shouldShowDebugger]);

  if (!shouldShowDebugger) return null;

  return (
    <>
      {/* Constraints container */}
      <motion.div
        ref={constraintsRef}
        className="pointer-events-none fixed inset-0"
        style={{ zIndex: 9998 }}
      />

      <AnimatePresence mode="wait">
        {!isExpanded ? (
          // Collapsed state - Fixed top-right corner section
          <motion.div
            id="mail-debugger-panel-collapsed"
            key=[redacted]
            initial={{ scale: 0, opacity: 0 }}
            animate={{ scale: 1, opacity: 1 }}
            exit={{ scale: 0, opacity: 0 }}
            whileHover={{ scale: 1.1 }}
            transition={{ type: 'spring', damping: 20, stiffness: 300 }}
            onClick={() => setIsExpanded(true)}
            style={{
              position: 'fixed',
              bottom: 0,
              right: 0,
              zIndex: 9999,
            }}
            className={cn('cursor-pointer select-none', className)}
          >
            <Container className="flex h-8 w-10 items-center justify-center rounded-tl-lg">
              <Bug className="h-4 w-4" />
            </Container>
          </motion.div>
        ) : (
          // Expanded state - full panel with Container
          <motion.div
            id="mail-debugger-panel-expanded"
            key=[redacted]
            drag
            dragControls={dragControls}
            dragConstraints={constraintsRef}
            dragElastic={0.2}
            dragMomentum={false}
            dragListener={false}
            initial={{ scale: 0.8, opacity: 0 }}
            animate={{ scale: 1, opacity: 1 }}
            exit={{ scale: 0.8, opacity: 0 }}
            transition={{ type: 'spring', damping: 20, stiffness: 300 }}
            style={{
              position: 'fixed',
              x: expandedPosition.x,
              y: expandedPosition.y,
              zIndex: 9999,
              width: panelWidth,
              height: panelHeight,
              cursor: isResizing
                ? isResizing === 'width'
                  ? 'col-resize'
                  : isResizing === 'height'
                    ? 'row-resize'
                    : 'nwse-resize'
                : 'default',
            }}
            className={cn('flex flex-col', className)}
          >
            <Container className="flex h-full flex-col" shadowSize="l">
              {/* Draggable Header */}
              <div
                className="flex cursor-move select-none items-center justify-between border-b border-gray-200 px-2 py-1 dark:border-gray-700"
                onPointerDown={(e) => dragControls.start(e)}
                style={{ touchAction: 'none' }}
              >
                <div className="flex items-center gap-1.5">
                  <GripHorizontal className="h-3 w-3 text-gray-400" />
                  <Mail className="h-3.5 w-3.5 text-blue-600 dark:text-blue-400" />
                  <span className="text-xs font-medium">Mail Debugger</span>
                  <div
                    className={cn(
                      'rounded-full px-1.5 py-0.5 text-xs',
                      currentThreadId
                        ? 'bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300'
                        : 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300',
                    )}
                  >
                    {currentThreadId ? 'Active Thread' : 'No Thread'}
                  </div>
                </div>
                <div className="flex items-center gap-1">
                  <button
                    onClick={handleRefresh}
                    className="rounded p-1 transition-colors hover:bg-gray-100 dark:hover:bg-gray-800"
                    title="Refresh data"
                  >
                    <RefreshCw className="h-3 w-3" />
                  </button>
                  <button
                    onClick={() => setIsExpanded(false)}
                    className="rounded p-1 transition-colors hover:bg-gray-100 dark:hover:bg-gray-800"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </div>
              </div>

              {/* Tabs Content */}
              <Tabs
                value={activeTab}
                onValueChange={setActiveTab}
                className="flex flex-1 flex-col overflow-hidden"
              >
                {/* Three rows of tabs */}
                <div className="mx-2 mt-1 flex flex-col gap-1">
                  {/* Row 1: Data + Docs tabs */}
                  <TabsList className="grid h-8 w-full grid-cols-6">
                    <TabsTrigger
                      value="currentThread"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <MessageSquare className="h-3 w-3" />
                      Current
                      {currentThreadId && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-blue-100 px-1 py-0.5 text-xs leading-none text-blue-700 dark:bg-blue-900 dark:text-blue-300">
                          1
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="threads"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Inbox className="h-3 w-3" />
                      Threads
                      {threadsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-green-100 px-1 py-0.5 text-xs leading-none text-green-700 dark:bg-green-900 dark:text-green-300">
                          {threadsCount}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="inbox"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Inbox className="h-3 w-3" />
                      Inbox
                      {inboxItemsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-sky-100 px-1 py-0.5 text-xs leading-none text-sky-700 dark:bg-sky-900 dark:text-sky-300">
                          {inboxItemsCount}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="conversations"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Users className="h-3 w-3" />
                      Convos
                      {conversationsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-purple-100 px-1 py-0.5 text-xs leading-none text-purple-700 dark:bg-purple-900 dark:text-purple-300">
                          {conversationsCount}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="conversationDocs"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <FileText className="h-3 w-3" />
                      Docs
                      {documentsCount > 0 && (
                        <span className={cn(
                          'ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full px-1 py-0.5 text-xs leading-none',
                          docSaveErrorCount > 0
                            ? 'bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300'
                            : 'bg-teal-100 text-teal-700 dark:bg-teal-900 dark:text-teal-300',
                        )}>
                          {docSaveErrorCount > 0 ? docSaveErrorCount : documentsCount}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="chatThreads"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <MessagesSquare className="h-3 w-3" />
                      Chat
                      {chatThreadsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-blue-100 px-1 py-0.5 text-xs leading-none text-blue-700 dark:bg-blue-900 dark:text-blue-300">
                          {chatThreadsCount}
                        </span>
                      )}
                    </TabsTrigger>
                  </TabsList>

                  {/* Row 2: Feature + Canvas tabs */}
                  <TabsList className="grid h-8 w-full grid-cols-6">
                    <TabsTrigger value="aop" className="flex items-center gap-1 px-2 py-1 text-xs">
                      <Bot className="h-3 w-3" />
                      AOP
                      {aopsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-amber-100 px-1 py-0.5 text-xs leading-none text-amber-700 dark:bg-amber-900 dark:text-amber-300">
                          {aopsCount}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger value="crm" className="flex items-center gap-1 px-2 py-1 text-xs">
                      <Briefcase className="h-3 w-3" />
                      CRM
                      {crmColumnsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-indigo-100 px-1 py-0.5 text-xs leading-none text-indigo-700 dark:bg-indigo-900 dark:text-indigo-300">
                          {crmColumnsCount}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="agentExecutions"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <History className="h-3 w-3" />
                      Agents
                      {agentExecutionsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-cyan-100 px-1 py-0.5 text-xs leading-none text-cyan-700 dark:bg-cyan-900 dark:text-cyan-300">
                          {agentExecutionsCount}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="calendar"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Calendar className="h-3 w-3" />
                      Cal
                      {calendarsCount + calendarEventsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-emerald-100 px-1 py-0.5 text-xs leading-none text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300">
                          {calendarsCount + calendarEventsCount}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger value="ux" className="flex items-center gap-1 px-2 py-1 text-xs">
                      <Layout className="h-3 w-3" />
                      UX
                    </TabsTrigger>
                    <TabsTrigger
                      value="agentCanvas"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Palette className="h-3 w-3" />
                      Canvas
                      {agentCanvasDataCount + pendingDraftsCount > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-violet-100 px-1 py-0.5 text-xs leading-none text-violet-700 dark:bg-violet-900 dark:text-violet-300">
                          {agentCanvasDataCount + pendingDraftsCount}
                        </span>
                      )}
                    </TabsTrigger>
                  </TabsList>

                  {/* Row 0: Deep debugger (timeline + freezes) */}
                  <TabsList className="grid h-8 w-full grid-cols-2">
                    <TabsTrigger
                      value="timeline"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Layers className="h-3 w-3" />
                      Timeline
                    </TabsTrigger>
                    <TabsTrigger
                      value="freezes"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Snowflake className="h-3 w-3" />
                      Freezes
                    </TabsTrigger>
                  </TabsList>

                  {/* Row 3: Cedar-OS agent + utility tabs */}
                  <TabsList className="grid h-8 w-full grid-cols-5">
                    <TabsTrigger
                      value="network"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Network className="h-3 w-3" />
                      Network
                      {agentConnectionLogs.length > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-purple-100 px-1 py-0.5 text-xs leading-none text-purple-700 dark:bg-purple-900 dark:text-purple-300">
                          {agentConnectionLogs.length}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="messages"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <MessageSquare className="h-3 w-3" />
                      Messages
                      {debugMessages.length > 0 && (
                        <span className="ml-0.5 flex h-4 min-w-[16px] items-center justify-center rounded-full bg-blue-100 px-1 py-0.5 text-xs leading-none text-blue-700 dark:bg-blue-900 dark:text-blue-300">
                          {debugMessages.length}
                        </span>
                      )}
                    </TabsTrigger>
                    <TabsTrigger
                      value="agentContext"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Database className="h-3 w-3" />
                      Context
                    </TabsTrigger>
                    <TabsTrigger
                      value="test"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <TestTube className="h-3 w-3" />
                      Test
                    </TabsTrigger>
                    <TabsTrigger
                      value="meetings"
                      className="flex items-center gap-1 px-2 py-1 text-xs"
                    >
                      <Video className="h-3 w-3" />
                      Meetings
                    </TabsTrigger>
                  </TabsList>
                </div>

                <div className="flex-1 overflow-hidden">
                  <TabsContent value="timeline" className="h-full">
                    <TimelineDebuggerTab />
                  </TabsContent>
                  <TabsContent value="freezes" className="h-full">
                    <FreezesDebuggerTab />
                  </TabsContent>
                  <TabsContent value="currentThread" className="h-full">
                    <CurrentThreadDebuggerTab
                      currentThreadId={currentThreadId}
                      currentConversationId={currentConversationId}
                      threadData={threadData}
                      conversationData={
                        currentConversationId ? allConversations[currentConversationId] : undefined
                      }
                      currentConversationList={currentConversationList}
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="threads" className="h-full">
                    <ThreadsDebuggerTab
                      threads={allThreadDataMap}
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="inbox" className="h-full">
                    <InboxDebuggerTab onCopy={handleCopy} copiedId={copiedId} />
                  </TabsContent>
                  <TabsContent value="conversations" className="h-full">
                    <ConversationsDebuggerTab
                      conversations={allConversations}
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="agentExecutions" className="h-full">
                    <AgentExecutionsDebuggerTab
                      executions={allAgentExecutions}
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="network" className="h-full">
                    <NetworkTab
                      logs={agentConnectionLogs}
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="messages" className="h-full">
                    <MessagesTab
                      messages={debugMessages}
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="agentContext" className="h-full">
                    <AgentContextDebuggerTab
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="aop" className="h-full">
                    <AOPDebuggerTab onCopy={handleCopy} copiedId={copiedId} />
                  </TabsContent>
                  <TabsContent value="crm" className="h-full">
                    <CRMTab onCopy={handleCopy} copiedId={copiedId} />
                  </TabsContent>
                  <TabsContent value="agentCanvas" className="h-full">
                    <AgentCanvasDebuggerTab />
                  </TabsContent>
                  <TabsContent value="calendar" className="h-full">
                    <CalendarDebuggerTab
                      calendars={calendars}
                      calendarEvents={calendarEvents}
                      selectedCalendarEventId={selectedCalendarEventId}
                      calendarEventToConversation={calendarEventToConversation}
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="ux" className="h-full">
                    <UXDebuggerTab
                      sidePanelMode={sidePanelMode}
                      navigation={navigation}
                      chatThreadId={chatThreadId}
                      activeCanvasId={activeCanvasId}
                      isGlobalCanvasOpen={isGlobalCanvasOpen}
                      activeView={activeView}
                      commandStack={commandStack}
                      commandModalItemId={commandModalItemId}
                      onCopy={handleCopy}
                      copiedId={copiedId}
                    />
                  </TabsContent>
                  <TabsContent value="test" className="h-full">
                    <TestDebuggerTab />
                  </TabsContent>
                  <TabsContent value="meetings" className="h-full">
                    <MeetingsDebuggerTab onCopy={handleCopy} copiedId={copiedId} />
                  </TabsContent>
                  <TabsContent value="conversationDocs" className="h-full">
                    <ConversationDocsDebuggerTab onCopy={handleCopy} copiedId={copiedId} />
                  </TabsContent>
                  <TabsContent value="chatThreads" className="h-full">
                    <ChatThreadsDebuggerTab onCopy={handleCopy} copiedId={copiedId} />
                  </TabsContent>
                </div>
              </Tabs>

              {/* Resize handles for bottom corners */}
              <>
                {/* Bottom-left corner handle */}
                <div
                  className="group absolute bottom-0 left-0 h-4 w-4 cursor-nwse-resize hover:bg-blue-400/30"
                  onMouseDown={(e) => startResize('bottom-left', e)}
                ></div>

                {/* Bottom-right corner handle */}
                <div
                  className="group absolute bottom-0 right-0 h-4 w-4 cursor-nwse-resize hover:bg-blue-400/30"
                  onMouseDown={(e) => startResize('bottom-right', e)}
                ></div>

                {/* Bottom edge handle for height only */}
                <div
                  className="absolute bottom-0 left-4 right-4 h-1 cursor-row-resize hover:bg-blue-400/30"
                  onMouseDown={(e) => startResize('height', e)}
                />

                {/* Right edge handle for width only */}
                <div
                  className="absolute bottom-4 right-0 top-12 w-1 cursor-col-resize hover:bg-blue-400/30"
                  onMouseDown={(e) => startResize('width', e)}
                />
              </>
            </Container>
          </motion.div>
        )}
      </AnimatePresence>
    </>
  );
};