feat: Implement workflow phases for test generation and execution

- Added Phase 1: Session Start to detect input mode and create test workflow session.
- Added Phase 2: Test Context Gather to gather test context via coverage analysis or codebase scan.
- Added Phase 3: Test Concept Enhanced to analyze test requirements using Gemini and generate multi-layered test requirements.
- Added Phase 4: Test Task Generate to create test-specific tasks based on analysis results.
- Added Phase 5: Test Cycle Execute to manage iterative test execution and fix cycles with adaptive strategies.
- Introduced BottomPanel component for terminal dashboard with Queue and Inspector tabs.
This commit is contained in:
catlog22
2026-02-14 21:35:55 +08:00
parent 0d805efe87
commit d535ab4749
27 changed files with 2004 additions and 2363 deletions

View File

@@ -2,49 +2,73 @@
// Terminal Dashboard Page
// ========================================
// Three-column Allotment layout for terminal execution management.
// Left: session groups + agent list
// Middle: issue + queue workflow panels
// Right: terminal workbench
// Top: GlobalKpiBar (real component)
// Bottom: BottomInspector (collapsible, real component)
// Left: session groups + agent list (with active session count badge)
// Middle: full-height IssuePanel
// Right: terminal workbench (or issue detail preview)
// Bottom: collapsible BottomPanel (Queue + Inspector tabs)
// Cross-cutting: AssociationHighlightProvider wraps the layout
import { useMemo } from 'react';
import { useIntl } from 'react-intl';
import { Allotment } from 'allotment';
import 'allotment/dist/style.css';
import { FolderTree } from 'lucide-react';
import { FolderTree, Activity } from 'lucide-react';
import { SessionGroupTree } from '@/components/terminal-dashboard/SessionGroupTree';
import { AgentList } from '@/components/terminal-dashboard/AgentList';
import { IssuePanel } from '@/components/terminal-dashboard/IssuePanel';
import { QueuePanel } from '@/components/terminal-dashboard/QueuePanel';
import { TerminalWorkbench } from '@/components/terminal-dashboard/TerminalWorkbench';
import { GlobalKpiBar } from '@/components/terminal-dashboard/GlobalKpiBar';
import { BottomInspector } from '@/components/terminal-dashboard/BottomInspector';
import { BottomPanel } from '@/components/terminal-dashboard/BottomPanel';
import { AssociationHighlightProvider } from '@/components/terminal-dashboard/AssociationHighlight';
import { Badge } from '@/components/ui/Badge';
import {
useSessionManagerStore,
selectGroups,
selectTerminalMetas,
} from '@/stores/sessionManagerStore';
import type { TerminalStatus } from '@/types/terminal-dashboard';
// ========== Main Page Component ==========
export function TerminalDashboardPage() {
const { formatMessage } = useIntl();
const groups = useSessionManagerStore(selectGroups);
const terminalMetas = useSessionManagerStore(selectTerminalMetas);
// Active session count for left column header badge
const sessionCount = useMemo(() => {
const allSessionIds = groups.flatMap((g) => g.sessionIds);
let activeCount = 0;
for (const sid of allSessionIds) {
const meta = terminalMetas[sid];
const status: TerminalStatus = meta?.status ?? 'idle';
if (status === 'active') {
activeCount++;
}
}
return activeCount > 0 ? activeCount : allSessionIds.length;
}, [groups, terminalMetas]);
return (
<div className="flex flex-col h-[calc(100vh-56px)] overflow-hidden">
{/* GlobalKpiBar at top (flex-shrink-0) */}
<GlobalKpiBar />
{/* AssociationHighlightProvider wraps the three-column layout + bottom inspector */}
{/* AssociationHighlightProvider wraps the three-column layout + bottom panel */}
<AssociationHighlightProvider>
{/* Three-column Allotment layout (flex-1) */}
<div className="flex-1 min-h-0">
<Allotment proportionalLayout={true}>
{/* Left column: Sessions */}
<Allotment.Pane preferredSize={250} minSize={180} maxSize={400}>
{/* Left column: Sessions + Agents */}
<Allotment.Pane preferredSize={220} minSize={180} maxSize={320}>
<div className="h-full border-r border-border bg-background flex flex-col">
<div className="px-3 py-2 border-b border-border shrink-0">
<div className="px-3 py-2 border-b border-border shrink-0 flex items-center justify-between">
<h2 className="text-sm font-semibold flex items-center gap-2">
<FolderTree className="w-4 h-4" />
{formatMessage({ id: 'terminalDashboard.columns.sessions' })}
</h2>
{sessionCount > 0 && (
<Badge variant="secondary" className="text-[10px] px-1.5 py-0 flex items-center gap-1">
<Activity className="w-3 h-3" />
{sessionCount}
</Badge>
)}
</div>
{/* SessionGroupTree takes remaining space */}
<div className="flex-1 min-h-0 overflow-y-auto">
@@ -57,23 +81,10 @@ export function TerminalDashboardPage() {
</div>
</Allotment.Pane>
{/* Middle column: Workflow (IssuePanel + QueuePanel vertical split) */}
<Allotment.Pane minSize={300}>
{/* Middle column: Full-height IssuePanel */}
<Allotment.Pane minSize={280}>
<div className="h-full border-r border-border bg-background overflow-hidden">
<Allotment vertical proportionalLayout={true}>
{/* Top: IssuePanel */}
<Allotment.Pane minSize={120}>
<div className="h-full overflow-hidden">
<IssuePanel />
</div>
</Allotment.Pane>
{/* Bottom: QueuePanel */}
<Allotment.Pane minSize={120}>
<div className="h-full overflow-hidden border-t border-border">
<QueuePanel />
</div>
</Allotment.Pane>
</Allotment>
<IssuePanel />
</div>
</Allotment.Pane>
@@ -86,8 +97,8 @@ export function TerminalDashboardPage() {
</Allotment>
</div>
{/* BottomInspector at bottom (flex-shrink-0) */}
<BottomInspector />
{/* BottomPanel: collapsible Queue + Inspector tabs (full-width) */}
<BottomPanel />
</AssociationHighlightProvider>
</div>
);