# Terminal Dashboard ## One-Liner **The Terminal Dashboard provides a terminal-first workspace with resizable panes, floating panels, and integrated tools for session monitoring and orchestration.** --- ## Pain Points Solved | Pain Point | Current State | Terminal Dashboard Solution | |------------|---------------|-----------------------------| | **Scattered terminals** | Multiple terminal windows | Unified tmux-style grid layout | | **No context linkage** | Can't associate terminal output with issues | Association highlight provider | | **Panel overload** | Fixed layout wastes space | Floating panels (mutually exclusive) | | **Missing tools** | Switch between apps | Integrated issues, queue, inspector, scheduler | | **Limited workspace** | Can't see code and terminals together | Resizable three-column layout | --- ## Overview **Location**: `ccw/frontend/src/pages/TerminalDashboardPage.tsx` **Purpose**: Terminal-first layout for multi-terminal session management with integrated tools and resizable panels. **Access**: Navigation → Terminal Dashboard (`/terminal-dashboard`) **Layout**: ``` +--------------------------------------------------------------------------+ | Dashboard Toolbar (panel toggles, layout presets, fullscreen) | +--------------------------------------------------------------------------+ | +----------------+-------------------------------------------+------------+ | | | Session | Terminal Grid (tmux-style) | File | | | | Group Tree | +----------+ +----------+ | Sidebar | | | | (resizable) | | Term 1 | | Term 2 | | (resizable)| | | | | +----------+ +----------+ | | | | | | +----------+ +----------+ | | | | | | | Term 3 | | Term 4 | | | | | | | +----------+ +----------+ | | | | +----------------+-------------------------------------------+------------+ | +--------------------------------------------------------------------------+ | [Floating Panel: Issues+Queue OR Inspector OR Execution OR Scheduler] | +--------------------------------------------------------------------------+ ``` --- ## Live Demo :::demo TerminalDashboardOverview # terminal-dashboard-overview.tsx /** * Terminal Dashboard Overview Demo * Shows the three-column layout with resizable panes and toolbar */ export function TerminalDashboardOverview() { const [fileSidebarOpen, setFileSidebarOpen] = React.useState(true) const [sessionSidebarOpen, setSessionSidebarOpen] = React.useState(true) const [activePanel, setActivePanel] = React.useState(null) return (
{/* Toolbar */}
Terminal Dashboard
{['Sessions', 'Files', 'Issues', 'Queue', 'Inspector', 'Scheduler'].map((item) => ( ))}
{/* Main Layout */}
{/* Session Sidebar */} {sessionSidebarOpen && (
Session Groups
{['Active Sessions', 'Completed', 'Archived'].map((group) => (
{group}
Session 1
Session 2
))}
)} {/* Terminal Grid */}
{[1, 2, 3, 4].map((i) => (
$ Terminal {i}
Working directory: /project
Type a command to begin...
))}
{/* File Sidebar */} {fileSidebarOpen && (
Project Files
{['src', 'docs', 'tests', 'package.json', 'README.md'].map((item) => (
📁 {item}
))}
)}
{/* Floating Panel */} {activePanel && (
{activePanel} Panel
{activePanel} content placeholder
)}
) } ::: --- ## Core Features | Feature | Description | |---------|-------------| | **Three-Column Layout** | Resizable panes using Allotment: Session tree (left), Terminal grid (center), File sidebar (right) | | **Terminal Grid** | Tmux-style split panes with layout presets (single, split-h, split-v, grid-2x2) | | **Session Group Tree** | Hierarchical view of CLI sessions with grouping by tags | | **Floating Panels** | Mutually exclusive overlay panels (Issues+Queue, Inspector, Execution Monitor, Scheduler) | | **Association Highlight** | Cross-panel linking between terminals, issues, and queue items | | **Layout Presets** | Quick layout buttons: single pane, horizontal split, vertical split, 2x2 grid | | **Launch CLI** | Config modal for creating new CLI sessions with tool, model, and settings | | **Fullscreen Mode** | Immersive mode hides app chrome (header + sidebar) | | **Feature Flags** | Panel visibility controlled by feature flags (queue, inspector, execution monitor) | --- ## Component Hierarchy ``` TerminalDashboardPage ├── AssociationHighlightProvider (context) ├── DashboardToolbar │ ├── Layout Preset Buttons (Single | Split-H | Split-V | Grid-2x2) │ ├── Panel Toggles (Sessions | Files | Issues | Queue | Inspector | Execution | Scheduler) │ ├── Fullscreen Toggle │ └── Launch CLI Button ├── Allotment (Three-Column Layout) │ ├── SessionGroupTree │ │ └── Session Group Items (collapsible) │ ├── TerminalGrid │ │ ├── GridGroupRenderer (recursive) │ │ └── TerminalPane │ └── FileSidebarPanel │ └── File Tree View └── FloatingPanel (multiple, mutually exclusive) ├── Issues+Queue (split panel) │ ├── IssuePanel │ └── QueueListColumn ├── QueuePanel (feature flag) ├── InspectorContent (feature flag) ├── ExecutionMonitorPanel (feature flag) └── SchedulerPanel ``` --- ## Props API ### TerminalDashboardPage | Prop | Type | Default | Description | |------|------|---------|-------------| | - | - | - | This page component accepts no props (state managed via hooks and Zustand stores) | ### DashboardToolbar | Prop | Type | Default | Description | |------|------|---------|-------------| | `activePanel` | `PanelId \| null` | `null` | Currently active floating panel | | `onTogglePanel` | `(panelId: PanelId) => void` | - | Callback to toggle panel visibility | | `isFileSidebarOpen` | `boolean` | `true` | File sidebar visibility state | | `onToggleFileSidebar` | `() => void` | - | Toggle file sidebar callback | | `isSessionSidebarOpen` | `boolean` | `true` | Session sidebar visibility state | | `onToggleSessionSidebar` | `() => void` | - | Toggle session sidebar callback | | `isFullscreen` | `boolean` | `false` | Fullscreen mode state | | `onToggleFullscreen` | `() => void` | - | Toggle fullscreen callback | ### FloatingPanel | Prop | Type | Default | Description | |------|------|---------|-------------| | `isOpen` | `boolean` | `false` | Panel open state | | `onClose` | `() => void` | - | Close callback | | `title` | `string` | - | Panel title | | `side` | `'left' \| 'right'` | `'left'` | Panel side | | `width` | `number` | `400` | Panel width in pixels | | `children` | `ReactNode` | - | Panel content | --- ## State Management ### Local State | State | Type | Description | |-------|------|-------------| | `activePanel` | `PanelId \| null` | Currently active floating panel (mutually exclusive) | | `isFileSidebarOpen` | `boolean` | File sidebar visibility | | `isSessionSidebarOpen` | `boolean` | Session sidebar visibility | ### Zustand Stores | Store | Selector | Purpose | |-------|----------|---------| | `workflowStore` | `selectProjectPath` | Current project path for file sidebar | | `appStore` | `selectIsImmersiveMode` | Fullscreen mode state | | `configStore` | `featureFlags` | Feature flag configuration | | `terminalGridStore` | Grid layout and focused pane state | | `executionMonitorStore` | Active execution count | | `queueSchedulerStore` | Scheduler status and settings | ### Panel ID Type ```typescript type PanelId = 'issues' | 'queue' | 'inspector' | 'execution' | 'scheduler'; ``` --- ## Usage Examples ### Basic Terminal Dashboard ```tsx import { TerminalDashboardPage } from '@/pages/TerminalDashboardPage' // The terminal dashboard is automatically rendered at /terminal-dashboard // No props needed - layout state managed internally ``` ### Using FloatingPanel Component ```tsx import { FloatingPanel } from '@/components/terminal-dashboard/FloatingPanel' import { IssuePanel } from '@/components/terminal-dashboard/IssuePanel' function CustomLayout() { const [isOpen, setIsOpen] = useState(false) return ( setIsOpen(false)} title="Issues" side="left" width={700} > ) } ``` ### Panel Toggle Pattern ```tsx import { useState, useCallback } from 'react' function usePanelToggle() { const [activePanel, setActivePanel] = useState(null) const togglePanel = useCallback((panelId: string) => { setActivePanel((prev) => (prev === panelId ? null : panelId)) }, []) const closePanel = useCallback(() => { setActivePanel(null) }, []) return { activePanel, togglePanel, closePanel } } ``` --- ## Interactive Demos ### Layout Presets Demo :::demo TerminalLayoutPresets # terminal-layout-presets.tsx /** * Terminal Layout Presets Demo * Interactive layout preset buttons */ export function TerminalLayoutPresets() { const [layout, setLayout] = React.useState('grid-2x2') const layouts = { single: 'grid-cols-1 grid-rows-1', 'split-h': 'grid-cols-2 grid-rows-1', 'split-v': 'grid-cols-1 grid-rows-2', 'grid-2x2': 'grid-cols-2 grid-rows-2', } return (

Terminal Layout Presets

{Object.keys(layouts).map((preset) => ( ))}
{Array.from({ length: layout === 'single' ? 1 : layout.includes('2x') ? 4 : 2 }).map((_, i) => (
$ Terminal {i + 1}
Ready for input...
))}
) } ::: ### Floating Panels Demo :::demo FloatingPanelsDemo # floating-panels-demo.tsx /** * Floating Panels Demo * Mutually exclusive overlay panels */ export function FloatingPanelsDemo() { const [activePanel, setActivePanel] = React.useState(null) const panels = [ { id: 'issues', title: 'Issues + Queue', side: 'left', width: 700 }, { id: 'queue', title: 'Queue', side: 'right', width: 400 }, { id: 'inspector', title: 'Inspector', side: 'right', width: 360 }, { id: 'execution', title: 'Execution Monitor', side: 'right', width: 380 }, { id: 'scheduler', title: 'Scheduler', side: 'right', width: 340 }, ] return (

Floating Panels

{panels.map((panel) => ( ))}

{activePanel ? `"${panels.find((p) => p.id === activePanel)?.title}" panel is open` : 'Click a button to open a floating panel'}

{/* Floating Panel Overlay */} {activePanel && (
p.id === activePanel)?.side === 'left' ? 'left-6' : 'right-6' }`} style={{ width: panels.find((p) => p.id === activePanel)?.width }} >
{panels.find((p) => p.id === activePanel)?.title}
Item 1
Item 2
Item 3
)}
) } ::: ### Resizable Panes Demo :::demo ResizablePanesDemo # resizable-panes-demo.tsx /** * Resizable Panes Demo * Simulates the Allotment resizable split behavior */ export function ResizablePanesDemo() { const [leftWidth, setLeftWidth] = React.useState(240) const [rightWidth, setRightWidth] = React.useState(280) const [isDragging, setIsDragging] = React.useState(null) const handleDragStart = (side) => (e) => { setIsDragging(side) e.preventDefault() } React.useEffect(() => { const handleMouseMove = (e) => { if (isDragging === 'left') { setLeftWidth(Math.max(180, Math.min(320, e.clientX))) } else if (isDragging === 'right') { setRightWidth(Math.max(200, Math.min(400, window.innerWidth - e.clientX))) } } const handleMouseUp = () => setIsDragging(null) if (isDragging) { window.addEventListener('mousemove', handleMouseMove) window.addEventListener('mouseup', handleMouseUp) return () => { window.removeEventListener('mousemove', handleMouseMove) window.removeEventListener('mouseup', handleMouseUp) } } }, [isDragging]) return (
{/* Left Sidebar */}
Session Groups
{['Active Sessions', 'Completed'].map((g) => (
{g}
))}
{/* Left Drag Handle */}
{/* Main Content */}
Terminal Grid Area
{/* Right Drag Handle */}
{/* Right Sidebar */}
Project Files
{['src/', 'docs/', 'tests/'].map((f) => (
{f}
))}
) } ::: --- ## Configuration ### Feature Flags | Flag | Controls | |------|----------| | `dashboardQueuePanelEnabled` | Queue panel visibility | | `dashboardInspectorEnabled` | Inspector panel visibility | | `dashboardExecutionMonitorEnabled` | Execution Monitor panel visibility | ### Layout Presets | Preset | Layout | |--------|--------| | **Single** | One terminal pane | | **Split-H** | Two panes side by side | | **Split-V** | Two panes stacked vertically | | **Grid-2x2** | Four panes in 2x2 grid | ### Panel Types | Panel | Content | Position | Feature Flag | |-------|---------|----------|--------------| | **Issues+Queue** | Combined Issues panel + Queue list column | Left (overlay) | - | | **Queue** | Full queue management panel | Right (overlay) | `dashboardQueuePanelEnabled` | | **Inspector** | Association chain inspector | Right (overlay) | `dashboardInspectorEnabled` | | **Execution Monitor** | Real-time execution tracking | Right (overlay) | `dashboardExecutionMonitorEnabled` | | **Scheduler** | Queue scheduler controls | Right (overlay) | - | --- ## Accessibility - **Keyboard Navigation**: - Tab - Navigate through toolbar buttons - Enter/Space - Activate toolbar buttons - Escape - Close floating panels - F11 - Toggle fullscreen mode - **ARIA Attributes**: - `aria-label` on toolbar buttons - `aria-expanded` on sidebar toggles - `aria-hidden` on inactive floating panels - `role="dialog"` on floating panels - **Screen Reader Support**: - Panel state announced when toggled - Layout changes announced - Focus management when panels open/close --- ## Related Links - [Orchestrator](/features/orchestrator) - Visual workflow editor - [Sessions](/features/sessions) - Session management - [Issue Hub](/features/issue-hub) - Issues, queue, discovery - [Explorer](/features/explorer) - File explorer - [Queue](/features/queue) - Queue management standalone page