Files
Claude-Code-Workflow/docs/features/queue.md
catlog22 2fb93d20e0 feat: add queue management and terminal dashboard documentation in Chinese
- Introduced comprehensive documentation for the queue management feature, detailing its pain points, core functionalities, and component structure.
- Added terminal dashboard documentation, highlighting its layout, core features, and usage examples.
- Created an index page in Chinese for Claude Code Workflow, summarizing its purpose and core features, along with quick links to installation and guides.
2026-03-01 10:52:46 +08:00

23 KiB

Queue Management

One-Liner

The Queue Management page provides centralized control over issue execution queues with scheduler controls, status monitoring, and session pool management.


Pain Points Solved

Pain Point Current State Queue Solution
Disorganized execution No unified task queue Centralized queue with grouped items
Unknown scheduler status Can't tell if scheduler is running Real-time status indicator (idle/running/paused)
No execution control Can't start/stop queue processing Start/Pause/Stop controls with confirmation
Concurrency limits Too many simultaneous sessions Configurable max concurrent sessions
No visibility Don't know what's queued Stats cards + item list with status tracking
Resource waste Idle sessions consuming resources Session pool overview with timeout config

Overview

Location: ccw/frontend/src/pages/QueuePage.tsx (legacy), ccw/frontend/src/components/terminal-dashboard/QueuePanel.tsx (current)

Purpose: View and manage issue execution queues with scheduler controls, progress tracking, and session pool management.

Access: Navigation → Issues → Queue tab OR Terminal Dashboard → Queue floating panel

Layout:

+--------------------------------------------------------------------------+
|  Queue Panel Header                                                        |
+--------------------------------------------------------------------------+
|  Scheduler Status Bar                                                       |
|  +----------------+  +-------------+  +-------------------------------+         |
|  | Status Badge   |  | Progress    |  | Concurrency (2/2)            |         |
|  +----------------+  +-------------+  +-------------------------------+         |
+--------------------------------------------------------------------------+
|  Scheduler Controls                                                          |
|  +--------+  +--------+  +--------+  +-----------+                      |
|  | Start  |  | Pause  |  | Stop   |  | Config    |                      |
|  +--------+  +--------+  +--------+  +-----------+                      |
+--------------------------------------------------------------------------+
|  Queue Items List                                                           |
|  +---------------------------------------------------------------------+    |
|  | QueueItemRow (status, issue_id, session_key, actions)              |    |
|  | - Status icon (pending/executing/completed/blocked/failed)         |    |
|  | - Issue ID / Item ID display                                        |    |
|  | - Session binding info                                              |    |
|  | - Progress indicator (for executing items)                          |    |
|  +---------------------------------------------------------------------+    |
|  | [More queue items...]                                               |    |
|  +---------------------------------------------------------------------+    |
+--------------------------------------------------------------------------+
|  Session Pool Overview (optional)                                           |
|  +--------------------------------------------------------------------------+
|  | Active Sessions | Idle Sessions | Total Sessions                      |
|  +--------------------------------------------------------------------------+

Live Demo

:::demo QueueManagementDemo

queue-management-demo.tsx

/**

  • Queue Management Demo
  • Shows scheduler controls and queue items list */ export function QueueManagementDemo() { const [schedulerStatus, setSchedulerStatus] = React.useState('idle') const [progress, setProgress] = React.useState(0)

const queueItems = [ { id: '1', status: 'completed', issueId: 'ISSUE-1', sessionKey: 'session-1' }, { id: '2', status: 'executing', issueId: 'ISSUE-2', sessionKey: 'session-2' }, { id: '3', status: 'pending', issueId: 'ISSUE-3', sessionKey: null }, { id: '4', status: 'pending', issueId: 'ISSUE-4', sessionKey: null }, { id: '5', status: 'blocked', issueId: 'ISSUE-5', sessionKey: null }, ]

const statusConfig = { idle: { label: 'Idle', color: 'bg-gray-500/20 text-gray-600 border-gray-500' }, running: { label: 'Running', color: 'bg-green-500/20 text-green-600 border-green-500' }, paused: { label: 'Paused', color: 'bg-amber-500/20 text-amber-600 border-amber-500' }, }

const itemStatusConfig = { completed: { icon: '✓', color: 'text-green-500', label: 'Completed' }, executing: { icon: '▶', color: 'text-blue-500', label: 'Executing' }, pending: { icon: '○', color: 'text-gray-400', label: 'Pending' }, blocked: { icon: '✕', color: 'text-red-500', label: 'Blocked' }, failed: { icon: '!', color: 'text-red-500', label: 'Failed' }, }

// Simulate progress when running React.useEffect(() => { if (schedulerStatus === 'running') { const interval = setInterval(() => { setProgress((p) => (p >= 100 ? 0 : p + 10)) }, 500) return () => clearInterval(interval) } }, [schedulerStatus])

const handleStart = () => { if (schedulerStatus === 'idle' || schedulerStatus === 'paused') { setSchedulerStatus('running') } }

const handlePause = () => { if (schedulerStatus === 'running') { setSchedulerStatus('paused') } }

const handleStop = () => { setSchedulerStatus('idle') setProgress(0) }

const currentConfig = statusConfig[schedulerStatus]

return (

{/* Header */}

Queue Management

Manage issue execution queue

  {/* Scheduler Status Bar */}
  <div className="border rounded-lg p-4 space-y-4">
    <div className="flex items-center justify-between">
      <span className={`px-3 py-1 rounded text-xs font-medium border ${currentConfig.color}`}>
        {currentConfig.label}
      </span>
      <div className="flex items-center gap-4 text-sm text-muted-foreground">
        <span>{queueItems.filter((i) => i.status === 'completed').length}/{queueItems.length} items</span>
        <span>2/2 concurrent</span>
      </div>
    </div>

    {/* Progress Bar */}
    {schedulerStatus === 'running' && (
      <div className="space-y-1">
        <div className="h-2 bg-muted rounded-full overflow-hidden">
          <div
            className="h-full bg-green-500 rounded-full transition-all"
            style={{ width: `${progress}%` }}
          />
        </div>
        <span className="text-xs text-muted-foreground">{progress}% complete</span>
      </div>
    )}

    {/* Scheduler Controls */}
    <div className="flex items-center gap-2">
      {(schedulerStatus === 'idle' || schedulerStatus === 'paused') && (
        <button
          onClick={handleStart}
          className="px-4 py-2 text-sm bg-green-500 text-white rounded hover:bg-green-600 flex items-center gap-2"
        >
          <span>▶</span> Start
        </button>
      )}
      {schedulerStatus === 'running' && (
        <button
          onClick={handlePause}
          className="px-4 py-2 text-sm bg-amber-500 text-white rounded hover:bg-amber-600 flex items-center gap-2"
        >
          <span>⏸</span> Pause
        </button>
      )}
      {schedulerStatus !== 'idle' && (
        <button
          onClick={handleStop}
          className="px-4 py-2 text-sm bg-red-500 text-white rounded hover:bg-red-600 flex items-center gap-2"
        >
          <span>⬛</span> Stop
        </button>
      )}
      <button className="px-4 py-2 text-sm border rounded hover:bg-accent">
        Config
      </button>
    </div>
  </div>

  {/* Queue Items List */}
  <div className="border rounded-lg">
    <div className="px-4 py-3 border-b bg-muted/30">
      <h4 className="text-sm font-semibold">Queue Items</h4>
    </div>
    <div className="divide-y max-h-80 overflow-auto">
      {queueItems.map((item) => {
        const config = itemStatusConfig[item.status]
        return (
          <div key={item.id} className="px-4 py-3 flex items-center gap-4 hover:bg-accent/50">
            <span className={`text-lg ${config.color}`}>{config.icon}</span>
            <div className="flex-1 min-w-0">
              <div className="flex items-center gap-2">
                <span className="text-sm font-medium">{item.issueId}</span>
                <span className={`text-xs px-2 py-0.5 rounded-full ${config.color} bg-opacity-10`}>
                  {config.label}
                </span>
              </div>
              {item.sessionKey && (
                <div className="text-xs text-muted-foreground mt-1">
                  Session: {item.sessionKey}
                </div>
              )}
            </div>
            {item.status === 'executing' && (
              <div className="w-20 h-1.5 bg-muted rounded-full overflow-hidden">
                <div className="h-full bg-blue-500 animate-pulse" style={{ width: '60%' }}/>
              </div>
            )}
          </div>
        )
      })}
    </div>
  </div>
</div>

) } :::


Core Features

Feature Description
Scheduler Status Real-time status indicator (idle/running/paused) with visual badge
Progress Tracking Progress bar showing overall queue completion percentage
Start/Pause/Stop Controls Control queue execution with confirmation dialog for stop action
Concurrency Display Shows current active sessions vs max concurrent sessions
Queue Items List Scrollable list of all queue items with status, issue ID, and session binding
Status Icons Visual indicators for item status (pending/executing/completed/blocked/failed)
Session Pool Overview of active, idle, and total sessions in the pool
Config Panel Adjust max concurrent sessions and timeout settings
Empty State Friendly message when queue is empty with instructions to add items

Component Hierarchy

QueuePage (legacy) / QueuePanel (current)
├── QueuePanelHeader
│   ├── Title
│   └── Tab Switcher (Queue | Orchestrator)
├── SchedulerBar (inline in QueueListColumn)
│   ├── Status Badge
│   ├── Progress + Concurrency
│   └── Control Buttons (Play/Pause/Stop)
├── QueueItemsList
│   └── QueueItemRow (repeating)
│       ├── Status Icon
│       ├── Issue ID / Item ID
│       ├── Session Binding
│       └── Progress (for executing items)
└── SchedulerPanel (standalone)
    ├── Status Section
    ├── Progress Bar
    ├── Control Buttons
    ├── Config Section
    │   ├── Max Concurrent Sessions
    │   ├── Session Idle Timeout
    │   └── Resume Key Binding Timeout
    └── Session Pool Overview

Props API

QueuePanel

Prop Type Default Description
embedded boolean false Whether panel is embedded in another component

SchedulerPanel

Prop Type Default Description
- - - This component accepts no props (all data from Zustand store)

QueueListColumn

Prop Type Default Description
- - - This component accepts no props (all data from Zustand store)

State Management

Zustand Stores

Store Selector Purpose
queueSchedulerStore selectQueueSchedulerStatus Current scheduler status (idle/running/paused)
queueSchedulerStore selectSchedulerProgress Overall queue completion percentage
queueSchedulerStore selectQueueItems List of all queue items
queueSchedulerStore selectCurrentConcurrency Active sessions count
queueSchedulerStore selectSchedulerConfig Scheduler configuration
queueSchedulerStore selectSessionPool Session pool overview
queueSchedulerStore selectSchedulerError Error message if any
issueQueueIntegrationStore selectAssociationChain Current association chain for highlighting
queueExecutionStore selectByQueueItem Execution data for queue item

Queue Item Status

type QueueItemStatus =
  | 'pending'      // Waiting to be executed
  | 'executing'    // Currently being processed
  | 'completed'    // Finished successfully
  | 'blocked'      // Blocked by dependency
  | 'failed';      // Failed with error

Scheduler Status

type QueueSchedulerStatus =
  | 'idle'     // No items or stopped
  | 'running'  // Actively processing items
  | 'paused';  // Temporarily paused

Usage Examples

Basic Queue Panel

import { QueuePanel } from '@/components/terminal-dashboard/QueuePanel'

function QueueSection() {
  return <QueuePanel />
}

Standalone Scheduler Panel

import { SchedulerPanel } from '@/components/terminal-dashboard/SchedulerPanel'

function SchedulerControls() {
  return <SchedulerPanel />
}

Queue List Column (Embedded)

import { QueueListColumn } from '@/components/terminal-dashboard/QueueListColumn'

function EmbeddedQueue() {
  return <QueueListColumn />
}

Queue Store Actions

import { useQueueSchedulerStore } from '@/stores/queueSchedulerStore'

function QueueActions() {
  const startQueue = useQueueSchedulerStore((s) => s.startQueue)
  const pauseQueue = useQueueSchedulerStore((s) => s.pauseQueue)
  const stopQueue = useQueueSchedulerStore((s) => s.stopQueue)
  const updateConfig = useQueueSchedulerStore((s) => s.updateConfig)

  const handleStart = () => startQueue()
  const handlePause = () => pauseQueue()
  const handleStop = () => stopQueue()
  const handleConfig = (config) => updateConfig(config)

  return (
    <div>
      <button onClick={handleStart}>Start</button>
      <button onClick={handlePause}>Pause</button>
      <button onClick={handleStop}>Stop</button>
      <button onClick={() => handleConfig({ maxConcurrentSessions: 4 })}>
        Set Max 4
      </button>
    </div>
  )
}

Interactive Demos

Queue Item Status Demo

:::demo QueueItemStatusDemo

queue-item-status-demo.tsx

/**

  • Queue Item Status Demo
  • Shows all possible queue item states */ export function QueueItemStatusDemo() { const itemStates = [ { status: 'pending', issueId: 'ISSUE-101', sessionKey: null }, { status: 'executing', issueId: 'ISSUE-102', sessionKey: 'cli-session-abc' }, { status: 'completed', issueId: 'ISSUE-103', sessionKey: 'cli-session-def' }, { status: 'blocked', issueId: 'ISSUE-104', sessionKey: null }, { status: 'failed', issueId: 'ISSUE-105', sessionKey: 'cli-session-ghi' }, ]

const statusConfig = { pending: { icon: '○', color: 'text-gray-400', bg: 'bg-gray-500/10', label: 'Pending' }, executing: { icon: '▶', color: 'text-blue-500', bg: 'bg-blue-500/10', label: 'Executing' }, completed: { icon: '✓', color: 'text-green-500', bg: 'bg-green-500/10', label: 'Completed' }, blocked: { icon: '✕', color: 'text-red-500', bg: 'bg-red-500/10', label: 'Blocked' }, failed: { icon: '!', color: 'text-red-500', bg: 'bg-red-500/10', label: 'Failed' }, }

return (

Queue Item Status States

{itemStates.map((item) => { const config = statusConfig[item.status] return (
<span className={text-2xl ${config.color}}>{config.icon}
{item.issueId} <span className={text-xs px-2 py-0.5 rounded-full ${config.bg} ${config.color}}> {config.label}
{item.sessionKey && (
Bound session: {item.sessionKey}
)}
{item.status === 'executing' && (
<div className="h-full bg-blue-500 animate-pulse" style={{ width: '60%' }}/>
60%
)}
) })}
) } :::

Scheduler Config Demo

:::demo SchedulerConfigDemo

scheduler-config-demo.tsx

/**

  • Scheduler Config Demo
  • Interactive configuration panel */ export function SchedulerConfigDemo() { const [config, setConfig] = React.useState({ maxConcurrentSessions: 2, sessionIdleTimeoutMs: 60000, resumeKeySessionBindingTimeoutMs: 300000, })

const formatMs = (ms) => { if (ms >= 60000) return ${ms / 60000}m if (ms >= 1000) return ${ms / 1000}s return ${ms}ms }

return (

Scheduler Configuration

Save

  <div className="space-y-4">
    {/* Max Concurrent Sessions */}
    <div className="space-y-2">
      <label className="text-sm font-medium">Max Concurrent Sessions</label>
      <div className="flex items-center gap-3">
        <input
          type="range"
          min="1"
          max="8"
          value={config.maxConcurrentSessions}
          onChange={(e) => setConfig({ ...config, maxConcurrentSessions: parseInt(e.target.value) })}
          className="flex-1"
        />
        <span className="text-sm font-medium w-8 text-center">{config.maxConcurrentSessions}</span>
      </div>
      <p className="text-xs text-muted-foreground">
        Maximum number of sessions to run simultaneously
      </p>
    </div>

    {/* Session Idle Timeout */}
    <div className="space-y-2">
      <label className="text-sm font-medium">Session Idle Timeout</label>
      <div className="flex items-center gap-3">
        <input
          type="range"
          min="10000"
          max="300000"
          step="10000"
          value={config.sessionIdleTimeoutMs}
          onChange={(e) => setConfig({ ...config, sessionIdleTimeoutMs: parseInt(e.target.value) })}
          className="flex-1"
        />
        <span className="text-sm font-medium w-12 text-right">{formatMs(config.sessionIdleTimeoutMs)}</span>
      </div>
      <p className="text-xs text-muted-foreground">
        Time before idle session is terminated
      </p>
    </div>

    {/* Resume Key Binding Timeout */}
    <div className="space-y-2">
      <label className="text-sm font-medium">Resume Key Binding Timeout</label>
      <div className="flex items-center gap-3">
        <input
          type="range"
          min="60000"
          max="600000"
          step="60000"
          value={config.resumeKeySessionBindingTimeoutMs}
          onChange={(e) => setConfig({ ...config, resumeKeySessionBindingTimeoutMs: parseInt(e.target.value) })}
          className="flex-1"
        />
        <span className="text-sm font-medium w-12 text-right">{formatMs(config.resumeKeySessionBindingTimeoutMs)}</span>
      </div>
      <p className="text-xs text-muted-foreground">
        Time to preserve resume key session binding
      </p>
    </div>
  </div>

  {/* Current Config Display */}
  <div className="border rounded-lg p-4 bg-muted/30">
    <h4 className="text-xs font-semibold mb-3">Current Configuration</h4>
    <dl className="space-y-2 text-sm">
      <div className="flex justify-between">
        <dt className="text-muted-foreground">Max Concurrent</dt>
        <dd className="font-medium">{config.maxConcurrentSessions} sessions</dd>
      </div>
      <div className="flex justify-between">
        <dt className="text-muted-foreground">Idle Timeout</dt>
        <dd className="font-medium">{formatMs(config.sessionIdleTimeoutMs)}</dd>
      </div>
      <div className="flex justify-between">
        <dt className="text-muted-foreground">Binding Timeout</dt>
        <dd className="font-medium">{formatMs(config.resumeKeySessionBindingTimeoutMs)}</dd>
      </div>
    </dl>
  </div>
</div>

) } :::


Configuration

Scheduler Config

Setting Type Default Description
maxConcurrentSessions number 2 Maximum sessions running simultaneously
sessionIdleTimeoutMs number 60000 Idle session timeout in milliseconds
resumeKeySessionBindingTimeoutMs number 300000 Resume key binding timeout in milliseconds

Queue Item Structure

interface QueueItem {
  item_id: string;
  issue_id?: string;
  sessionKey?: string;
  status: QueueItemStatus;
  execution_order: number;
  created_at?: number;
  updated_at?: number;
}

Accessibility

  • Keyboard Navigation:

    • Tab - Navigate through queue items and controls
    • Enter/Space - Activate buttons
    • Escape - Close dialogs
  • ARIA Attributes:

    • aria-label on control buttons
    • aria-live regions for status updates
    • aria-current for active queue item
    • role="list" on queue items list
  • Screen Reader Support:

    • Status changes announced
    • Progress updates spoken
    • Error messages announced