Project Source Code Summary
Generated on: 2026-03-20

Directory Structure:
/
├── .env.example
├── .gitignore
├── index.html
├── metadata.json
├── package.json
├── tsconfig.json
├── vite.config.ts
└── src/
    ├── App.tsx
    ├── index.css
    ├── main.tsx
    ├── types.ts
    └── lib/
        └── utils.ts

================================================================================
FILE: /.env.example
================================================================================
# GEMINI_API_KEY: Required for Gemini AI API calls.
# AI Studio automatically injects this at runtime from user secrets.
# Users configure this via the Secrets panel in the AI Studio UI.
GEMINI_API_KEY="MY_GEMINI_API_KEY"

# APP_URL: The URL where this applet is hosted.
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
# Used for self-referential links, OAuth callbacks, and API endpoints.
APP_URL="MY_APP_URL"

================================================================================
FILE: /.gitignore
================================================================================
node_modules/
build/
dist/
coverage/
.DS_Store
*.log
.env*
!.env.example

================================================================================
FILE: /index.html
================================================================================
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Google AI Studio App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

================================================================================
FILE: /metadata.json
================================================================================
{
  "name": "PentAGI 赛博作战中心",
  "description": "先进的 AI 驱动自主渗透测试与安全自动化平台，具备实时可视化功能。",
  "requestFramePermissions": []
}

================================================================================
FILE: /package.json
================================================================================
{
  "name": "react-example",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite --port=3000 --host=0.0.0.0",
    "build": "vite build",
    "preview": "vite preview",
    "clean": "rm -rf dist",
    "lint": "tsc --noEmit"
  },
  "dependencies": {
    "@google/genai": "^1.29.0",
    "@tailwindcss/vite": "^4.1.14",
    "@vitejs/plugin-react": "^5.0.4",
    "clsx": "^2.1.1",
    "dotenv": "^17.2.3",
    "express": "^4.21.2",
    "lucide-react": "^0.546.0",
    "motion": "^12.38.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "recharts": "^3.8.0",
    "tailwind-merge": "^3.5.0",
    "vite": "^6.2.0"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^22.14.0",
    "autoprefixer": "^10.4.21",
    "tailwindcss": "^4.1.14",
    "tsx": "^4.21.0",
    "typescript": "~5.8.2",
    "vite": "^6.2.0"
  }
}

================================================================================
FILE: /tsconfig.json
================================================================================
{
  "compilerOptions": {
    "target": "ES2022",
    "experimentalDecorators": true,
    "useDefineForClassFields": false,
    "module": "ESNext",
    "lib": [
      "ES2022",
      "DOM",
      "DOM.Iterable"
    ],
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "isolatedModules": true,
    "moduleDetection": "force",
    "allowJs": true,
    "jsx": "react-jsx",
    "paths": {
      "@/*": [
        "./*"
      ]
    },
    "allowImportingTsExtensions": true,
    "noEmit": true
  }
}

================================================================================
FILE: /vite.config.ts
================================================================================
import tailwindcss from '@tailwindcss/vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import {defineConfig, loadEnv} from 'vite';

export default defineConfig(({mode}) => {
  const env = loadEnv(mode, '.', '');
  return {
    plugins: [react(), tailwindcss()],
    define: {
      'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
    },
    resolve: {
      alias: {
        '@': path.resolve(__dirname, '.'),
      },
    },
    server: {
      // HMR is disabled in AI Studio via DISABLE_HMR env var.
      // Do not modify—file watching is disabled to prevent flickering during agent edits.
      hmr: process.env.DISABLE_HMR !== 'true',
    },
  };
});

================================================================================
FILE: /src/main.tsx
================================================================================
import {StrictMode} from 'react';
import {createRoot} from 'react-dom/client';
import App from './App.tsx';
import './index.css';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

================================================================================
FILE: /src/index.css
================================================================================
@import "tailwindcss";

@theme {
  --color-cyber-bg: #050505;
  --color-cyber-panel: #0a0a0a;
  --color-cyber-accent: #00ff9f;
  --color-cyber-border: #1a1a1a;
  --color-cyber-text: #e0e0e0;
  --color-cyber-muted: #666666;
  
  --font-mono: "JetBrains Mono", "Fira Code", monospace;
}

@layer base {
  body {
    @apply bg-cyber-bg text-cyber-text font-mono overflow-hidden;
  }
}

.custom-scrollbar::-webkit-scrollbar {
  width: 4px;
  height: 4px;
}

.custom-scrollbar::-webkit-scrollbar-track {
  background: transparent;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
  background: #1a1a1a;
  border-radius: 2px;
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background: #00ff9f;
}

.neon-glow {
  text-shadow: 0 0 5px rgba(0, 255, 159, 0.5), 0 0 10px rgba(0, 255, 159, 0.3);
}

.neon-border {
  box-shadow: 0 0 5px rgba(0, 255, 159, 0.2);
  border-color: rgba(0, 255, 159, 0.3);
}

================================================================================
FILE: /src/types.ts
================================================================================
export interface Task {
  id: string;
  title: string;
  status: 'pending' | 'running' | 'completed' | 'failed';
  description?: string;
}

export interface Flow {
  id: string;
  name: string;
  status: 'pending' | 'running' | 'completed' | 'failed';
  progress: number;
  target: string;
  createdAt: string;
  duration?: string;
  agent?: string;
}

export interface Agent {
  id: string;
  name?: string;
  role: string;
  status: string;
  currentThought: string;
  tokenUsage: number;
}

export interface Action {
  id: string;
  timestamp: string;
  type: string;
  command: string;
  status: 'success' | 'failed' | 'running';
}

export interface Evidence {
  id: string;
  host: string;
  severity: 'Critical' | 'High' | 'Medium' | 'Low';
  cve?: string;
  poc: string;
  cvss: number;
  description?: string;
}

export interface Artifact {
  id: string;
  type: 'screenshot' | 'report' | 'log' | 'poc';
  url: string;
  title: string;
  timestamp: string;
}

export interface Report {
  id: string;
  executiveSummary: string;
  generatedAt: string;
  riskMatrix: {
    host: string;
    severity: string;
    cvss: number;
  }[];
}

================================================================================
FILE: /src/lib/utils.ts
================================================================================
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

================================================================================
FILE: /src/App.tsx
================================================================================
import { 
  Activity, AlertTriangle, CheckCircle2, ChevronRight, 
  Clock, Cpu, Database, FileDown, FileText, 
  LayoutDashboard, List, Lock, Network, Play, 
  Search, Settings, Shield, Terminal as TerminalIcon, 
  Zap, Info, Pause, SkipForward, Upload, 
  ExternalLink, Eye, Download, Trash2, HelpCircle,
  Square, Command, User, BarChart3, Loader2, Check,
  Globe, Image as ImageIcon, Terminal
} from 'lucide-react';
import { motion, AnimatePresence } from 'motion/react';
import { 
  AreaChart, Area, XAxis, YAxis, CartesianGrid, 
  Tooltip as RechartsTooltip, ResponsiveContainer, 
  PieChart, Pie, Cell, Tooltip
} from 'recharts';
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { 
  Flow, Agent, Action, Evidence, Artifact, Report, Task 
} from './types';
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';

function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

// --- MOCK DATA ---
const MOCK_TASKS: Task[] = [
  { id: 't1', title: '解析拓扑结构', status: 'completed', description: '分析目标网络结构' },
  { id: 't2', title: '端口扫描 (Nmap)', status: 'completed', description: '探测开放端口与服务' },
  { id: 't3', title: 'Web 目录爆破', status: 'running', description: '寻找隐藏路径与后台' },
  { id: 't4', title: 'SQL 注入测试', status: 'pending', description: '验证输入点是否存在注入' },
  { id: 't5', title: '权限维持与提权', status: 'pending', description: '获取更高系统权限' },
];

const MOCK_FLOWS: Flow[] = [
  { id: 'F01', name: '靶机A-SQL注入实战', status: 'running', progress: 60, duration: '12m 30s', agent: 'WebSecAgent', target: '10.0.0.5', createdAt: '2026-03-20 09:00' },
  { id: 'F02', name: '公司内部网络拓扑扫描', status: 'completed', progress: 100, duration: '45m 00s', agent: 'Researcher', target: '192.168.1.0/24', createdAt: '2026-03-19 14:20' },
];

const MOCK_AGENTS: Agent[] = [
  { id: 'a1', name: 'Researcher', role: '侦察者', status: 'thinking', currentThought: '正在分析 Nmap 结果...发现 80 端口开放。', tokenUsage: 4500 },
  { id: 'a2', name: 'Executor', role: '执行者', status: 'idle', currentThought: '收到指令，正在启动 DirBuster 容器...', tokenUsage: 1200 },
  { id: 'a3', name: 'Analyzer', role: '代码分析师', status: 'idle', currentThought: '等待 Web 目录扫描结果进行深度分析。', tokenUsage: 8900 },
];

const MOCK_THOUGHTS = [
  { agent: 'Researcher', text: '思考：接下来应使用 DirBuster 探测隐藏路径，寻找后台登录入口。', timestamp: '14:23:01' },
  { agent: 'Executor', text: '收到指令，正在启动 DirBuster 容器... 目标: http://10.0.0.5/', timestamp: '14:23:05' },
  { agent: 'Researcher', text: '发现 /admin/login.php，这是一个高价值目标。', timestamp: '14:23:10' },
  { agent: 'Analyzer', text: '分析登录页面源码... 发现可能存在 SQL 注入的参数 "user"。', timestamp: '14:23:15' },
];

const MOCK_TERMINAL_LOGS = [
  'user@pentagi:~$ dirsearch -u http://10.0.0.5/ -e php',
  '[14:23:01] Starting: ',
  '[14:23:05] 200 -   12KB - /admin/login.php  <-- FOUND!',
  '[14:23:10] 200 -    5KB - /config.php',
  '[14:23:15] 403 -    1KB - /server-status',
  '[14:23:20] Task Completed.',
];

const MOCK_EVIDENCE: Evidence[] = [
  { id: 'e1', host: '10.0.0.5', severity: 'High', cvss: 8.5, description: '发现后台登录入口 /admin/login.php', poc: 'dirsearch -u http://10.0.0.5/' },
  { id: 'e2', host: '10.0.0.5', severity: 'Critical', cvss: 9.8, description: 'SQL 注入漏洞验证成功', poc: 'sqlmap -u "http://10.0.0.5/admin/login.php?user=admin"' },
];

const MOCK_ACTIONS: Action[] = [
  { id: 'a1', type: 'scan', command: 'nmap -sV 10.0.0.5', status: 'success', timestamp: '14:20:00' },
  { id: 'a2', type: 'exploit', command: 'dirsearch -u http://10.0.0.5/', status: 'success', timestamp: '14:23:01' },
  { id: 'a3', type: 'exploit', command: 'sqlmap -u "http://10.0.0.5/admin/login.php?user=admin"', status: 'running', timestamp: '14:25:10' },
];

const MOCK_ARTIFACTS: Artifact[] = [
  { id: 'art1', type: 'screenshot', url: 'https://picsum.photos/seed/pentest1/400/300', title: 'Admin Login Page', timestamp: '14:23:05' },
  { id: 'art2', type: 'log', url: '#', title: 'Nmap Scan Results', timestamp: '14:22:45' },
];

const RISK_DATA = [
  { name: '严重 (Critical)', value: 1, color: '#ff0000' },
  { name: '高危 (High)', value: 1, color: '#ff4400' },
  { name: '中危 (Medium)', value: 1, color: '#ffaa00' },
  { name: '低危 (Low)', value: 0, color: '#00ff00' },
];

const ACTIVITY_DATA = [
  { time: '09:00', actions: 12 },
  { time: '09:05', actions: 18 },
  { time: '09:10', actions: 45 },
  { time: '09:15', actions: 32 },
  { time: '09:20', actions: 67 },
  { time: '09:25', actions: 89 },
  { time: '09:30', actions: 54 },
];

// --- Components ---

const StatusBadge = ({ status }: { status: string }) => {
  const colors: Record<string, string> = {
    running: 'text-cyber-accent border-cyber-accent/30 bg-cyber-accent/10',
    completed: 'text-emerald-500 border-emerald-500/30 bg-emerald-500/10',
    pending: 'text-cyber-muted border-cyber-border bg-cyber-border/20',
    failed: 'text-red-500 border-red-500/30 bg-red-500/10',
  };
  
  const labels: Record<string, string> = {
    running: '运行中',
    completed: '已完成',
    pending: '等待中',
    failed: '失败',
  };

  return (
    <span className={`px-2 py-0.5 rounded-full text-[10px] font-bold border ${colors[status] || colors.pending}`}>
      {labels[status] || status}
    </span>
  );
};

const Panel = ({ title, children, className, icon: Icon, badge }: { title: string, children: React.ReactNode, className?: string, icon?: any, badge?: string }) => (
  <div className={`bg-black/40 border border-cyber-border rounded-lg overflow-hidden flex flex-col ${className}`}>
    <div className="px-4 py-2 border-b border-cyber-border flex items-center justify-between bg-cyber-border/10">
      <div className="flex items-center gap-2">
        {Icon && <Icon size={14} className="text-cyber-accent" />}
        <h3 className="text-xs font-bold tracking-wider text-cyber-accent uppercase">{title}</h3>
      </div>
      {badge && <span className="text-[10px] px-1.5 py-0.5 bg-cyber-accent/20 text-cyber-accent rounded font-mono">{badge}</span>}
    </div>
    <div className="flex-1 p-4 overflow-auto custom-scrollbar">
      {children}
    </div>
  </div>
);

const ConceptTooltip = ({ text, concept, explanation }: { text: string, concept: string, explanation: string }) => {
  const [show, setShow] = useState(false);
  
  return (
    <span className="relative inline-block group">
      <span 
        className="text-blue-400 underline decoration-dotted cursor-help"
        onMouseEnter={() => setShow(true)}
        onMouseLeave={() => setShow(false)}
      >
        {text}
      </span>
      <AnimatePresence>
        {show && (
          <motion.div 
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: 10 }}
            className="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 w-48 p-2 bg-zinc-900 border border-cyber-accent rounded text-[10px] z-50 shadow-xl"
          >
            <div className="font-bold text-cyber-accent mb-1">{concept}</div>
            <div className="text-cyber-muted leading-relaxed">{explanation}</div>
          </motion.div>
        )}
      </AnimatePresence>
    </span>
  );
};

export default function App() {
  const [command, setCommand] = useState('');
  const [isSidebarExpanded, setIsSidebarExpanded] = useState(false);
  const [teachingMode, setTeachingMode] = useState(true);
  const [sandboxStatus, setSandboxStatus] = useState<'idle' | 'running' | 'success'>('idle');
  const [showReport, setShowReport] = useState(false);
  const [activeFlow, setActiveFlow] = useState(MOCK_FLOWS[0]);
  const [thinkingText, setThinkingText] = useState('');
  const [fullThinkingText, setFullThinkingText] = useState('正在分析目标系统的网络拓扑结构...');

  const runSandbox = () => {
    setSandboxStatus('running');
    setTimeout(() => {
      setSandboxStatus('success');
      setShowReport(true);
    }, 3000);
  };

  useEffect(() => {
    const texts = [
      '正在扫描开放端口...',
      '发现 80/tcp 端口开放，正在识别服务版本...',
      '识别到 Apache/2.4.41 (Ubuntu)...',
      '正在启动目录爆破工具...',
      '发现敏感目录 /admin/login.php...',
      '正在尝试 SQL 注入攻击向量...',
    ];
    let i = 0;
    const interval = setInterval(() => {
      setFullThinkingText(texts[i % texts.length]);
      i++;
    }, 4000);
    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    let currentText = '';
    let i = 0;
    const typingInterval = setInterval(() => {
      if (i < fullThinkingText.length) {
        currentText += fullThinkingText[i];
        setThinkingText(currentText);
        i++;
      } else {
        clearInterval(typingInterval);
      }
    }, 50);
    return () => clearInterval(typingInterval);
  }, [fullThinkingText]);

  return (
    <div className="h-screen w-screen flex flex-col bg-cyber-bg text-cyber-text selection:bg-cyber-accent selection:text-black">
      {/* Top Bar */}
      <header className="h-14 border-b border-cyber-border flex items-center px-6 justify-between bg-cyber-panel/50 backdrop-blur-md z-50">
        <div className="flex items-center gap-4">
          <div className="flex items-center gap-2">
            <div className="w-8 h-8 bg-cyber-accent rounded flex items-center justify-center text-black font-black italic shadow-[0_0_15px_rgba(0,255,0,0.4)]">P</div>
            <span className="font-bold tracking-tighter text-xl neon-glow">PentAGI</span>
          </div>
          <div className="h-4 w-[1px] bg-cyber-border mx-2" />
          <div className="flex items-center gap-3 text-[10px] text-cyber-muted uppercase tracking-widest">
            <div className="flex items-center gap-1.5">
              <Activity size={12} className="text-cyber-accent animate-pulse" />
              <span>5 个智能体活跃</span>
            </div>
            <span className="opacity-30">|</span>
            <div className="flex items-center gap-1.5">
              <Cpu size={12} />
              <span>Qwen2.5-32B</span>
            </div>
          </div>
        </div>

        <div className="flex-1 max-w-2xl mx-8 flex gap-2 relative group">
          <div className="relative flex-1">
            <Command className="absolute left-3 top-1/2 -translate-y-1/2 text-cyber-muted group-focus-within:text-cyber-accent transition-colors" size={16} />
            <input 
              type="text"
              placeholder="Cmd+K: '对 192.168.1.0/24 进行全面渗透测试'..."
              className="w-full bg-white/5 border border-cyber-border rounded-md py-2 pl-10 pr-4 text-sm focus:outline-none focus:border-cyber-accent/50 focus:ring-1 focus:ring-cyber-accent/20 transition-all placeholder:text-cyber-muted/50"
              value={command}
              onChange={(e) => setCommand(e.target.value)}
            />
            <div className="absolute right-3 top-1/2 -translate-y-1/2 flex gap-1">
              <kbd className="px-1.5 py-0.5 rounded bg-white/10 text-[10px] text-cyber-muted border border-white/10">⌘</kbd>
              <kbd className="px-1.5 py-0.5 rounded bg-white/10 text-[10px] text-cyber-muted border border-white/10">K</kbd>
            </div>
          </div>
          <button className="px-3 py-2 bg-white/5 border border-cyber-border rounded-md text-cyber-muted hover:text-cyber-accent hover:border-cyber-accent/50 transition-all flex items-center gap-2 text-xs font-bold">
            <Upload size={14} />
            <span>上传文档</span>
          </button>
        </div>

        <div className="flex items-center gap-6">
          <div className="flex items-center gap-3 bg-white/5 border border-cyber-border rounded-full px-3 py-1">
            <span className="text-[9px] text-cyber-muted uppercase font-bold tracking-tighter">教学模式</span>
            <button 
              onClick={() => setTeachingMode(!teachingMode)}
              className={cn(
                "w-8 h-4 rounded-full relative transition-all duration-300",
                teachingMode ? "bg-cyber-accent" : "bg-white/10"
              )}
            >
              <motion.div 
                animate={{ x: teachingMode ? 16 : 2 }}
                className="absolute top-1 w-2 h-2 rounded-full bg-black shadow-sm"
              />
            </button>
          </div>
          <div className="flex gap-4">
            <div className="text-right">
              <div className="text-[9px] text-cyber-muted uppercase font-bold">总 Token 消耗</div>
              <div className="text-sm font-mono text-cyber-accent leading-none">18,742</div>
            </div>
            <div className="text-right">
              <div className="text-[9px] text-cyber-muted uppercase font-bold">已发现漏洞</div>
              <div className="text-sm font-mono text-red-500 leading-none">27</div>
            </div>
          </div>
          <button className="p-2 hover:bg-white/5 rounded-full transition-colors">
            <Settings size={20} className="text-cyber-muted" />
          </button>
          <div className="w-8 h-8 rounded-full bg-gradient-to-br from-cyber-accent to-emerald-900 border border-cyber-accent/50 flex items-center justify-center text-[10px] font-bold text-black">AD</div>
        </div>
      </header>

      <main className="flex-1 flex overflow-hidden">
        {/* Sidebar */}
        <motion.nav 
          initial={false}
          animate={{ width: isSidebarExpanded ? 200 : 64 }}
          onMouseEnter={() => setIsSidebarExpanded(true)}
          onMouseLeave={() => setIsSidebarExpanded(false)}
          className="border-r border-cyber-border flex flex-col items-start py-6 gap-4 bg-cyber-panel/30 transition-all duration-300 overflow-hidden"
        >
          {[
            { icon: LayoutDashboard, label: '仪表盘', active: true },
            { icon: Network, label: '知识图谱' },
            { icon: Shield, label: '智能体' },
            { icon: FileText, label: '报告中心' },
            { icon: Globe, label: '资产清单' },
            { icon: Database, label: '漏洞库' },
          ].map((item, idx) => (
            <button key={idx} className={cn(
              "w-full px-4 py-3 flex items-center gap-4 transition-all group relative",
              item.active ? "text-cyber-accent" : "text-cyber-muted hover:text-cyber-text"
            )}>
              <div className={cn(
                "p-1 rounded-lg transition-all",
                item.active ? "bg-cyber-accent/10" : "group-hover:bg-white/5"
              )}>
                <item.icon size={22} />
              </div>
              <motion.span 
                initial={false}
                animate={{ opacity: isSidebarExpanded ? 1 : 0, x: isSidebarExpanded ? 0 : -10 }}
                className="text-xs font-bold whitespace-nowrap"
              >
                {item.label}
              </motion.span>
              {item.active && <div className="absolute left-0 top-1/4 bottom-1/4 w-1 bg-cyber-accent rounded-r shadow-[0_0_10px_#00ff00]" />}
            </button>
          ))}
        </motion.nav>

        {/* Content Area */}
        <div className="flex-1 flex flex-col p-4 gap-4 overflow-hidden">
          {/* Top Row: Flow Info & Controls */}
          <div className="flex items-center justify-between bg-cyber-panel/50 border border-cyber-border p-4 rounded-lg backdrop-blur-sm relative overflow-hidden">
            <div className="absolute top-0 left-0 w-1 h-full bg-cyber-accent shadow-[0_0_10px_#00ff00]" />
            <div className="flex items-center gap-4">
              <div>
                <div className="text-[10px] text-cyber-muted uppercase font-bold tracking-widest">当前任务流程</div>
                <div className="text-lg font-bold flex items-center gap-2">
                  {activeFlow.name}
                  <span className="px-2 py-0.5 rounded bg-cyber-accent/20 text-cyber-accent text-[10px] uppercase font-bold border border-cyber-accent/30 animate-pulse">
                    正在运行
                  </span>
                </div>
              </div>
              <div className="h-8 w-[1px] bg-cyber-border mx-4" />
              <div className="w-64">
                <div className="flex justify-between text-[10px] text-cyber-muted mb-1">
                  <span>执行进度: {MOCK_TASKS.find(t => t.status === 'running')?.title || '正在分析'}</span>
                  <span className="text-cyber-accent">{activeFlow.progress}%</span>
                </div>
                <div className="h-1.5 w-full bg-white/5 rounded-full overflow-hidden">
                  <motion.div 
                    initial={{ width: 0 }}
                    animate={{ width: `${activeFlow.progress}%` }}
                    transition={{ duration: 1, ease: "easeOut" }}
                    className="h-full bg-cyber-accent shadow-[0_0_10px_#00ff00]"
                  />
                </div>
              </div>
              <div className="h-8 w-[1px] bg-cyber-border mx-4" />
              <div className="flex gap-6">
                <div>
                  <div className="text-[9px] text-cyber-muted uppercase font-bold">目标资产</div>
                  <div className="text-xs font-mono text-cyber-accent">{activeFlow.target}</div>
                </div>
                <div>
                  <div className="text-[9px] text-cyber-muted uppercase font-bold">已用时间</div>
                  <div className="text-xs font-mono">01:42:05</div>
                </div>
              </div>
            </div>
            <div className="flex gap-2">
              <button className="flex items-center gap-2 px-4 py-2 bg-cyber-accent text-black font-bold rounded hover:brightness-110 transition-all text-xs shadow-[0_0_15px_rgba(0,255,0,0.3)]">
                <Square size={14} fill="currentColor" /> 停止全部
              </button>
              <button className="flex items-center gap-2 px-4 py-2 bg-white/5 border border-cyber-border text-cyber-text font-bold rounded hover:bg-white/10 transition-all text-xs">
                <Download size={14} /> 导出追踪
              </button>
            </div>
          </div>

          {/* Grid Layout - Optimized to fill space */}
          <div className="flex-1 grid grid-cols-12 grid-rows-6 gap-4 overflow-hidden">
            {/* Agent Thinking & Chat */}
            <Panel title="智能体实时思考与对话" className="col-span-4 row-span-4" icon={Terminal} badge="实时">
              <div className="space-y-4 font-mono text-xs leading-relaxed">
                <div className="text-cyber-muted">[{new Date().toLocaleTimeString()}] 系统: 正在初始化多智能体编排...</div>
                <div className="text-cyber-accent whitespace-pre-wrap min-h-[3em]">
                  {thinkingText}
                  <span className="inline-block w-2 h-4 bg-cyber-accent animate-pulse ml-1 align-middle" />
                </div>
                
                <div className="space-y-4 pt-4 border-t border-cyber-border">
                  {MOCK_THOUGHTS.map((thought, idx) => (
                    <div key={idx} className="group">
                      <div className="flex items-center gap-2 text-cyber-muted mb-1 group-hover:text-cyber-accent transition-colors">
                        {thought.agent === 'Researcher' ? <Search size={10} /> : thought.agent === 'Executor' ? <Zap size={10} /> : <Cpu size={10} />}
                        <span className="uppercase font-bold tracking-tighter text-[9px]">{thought.agent}</span>
                        <span className="text-[8px] opacity-50 ml-auto">{thought.timestamp}</span>
                      </div>
                      <p className={cn(
                        "text-cyber-text italic bg-white/5 p-2 rounded border-l-2 transition-all group-hover:bg-white/10",
                        thought.agent === 'Researcher' ? "border-cyber-accent" : thought.agent === 'Executor' ? "border-red-500" : "border-blue-500"
                      )}>
                        {thought.text.includes('SQL 注入') ? (
                          <>
                            正在分析登录页面源码... 发现可能存在 <ConceptTooltip text="SQL 注入" concept="SQL Injection" explanation="一种代码注入技术，通过在输入字段中插入恶意 SQL 语句，从而操纵后端数据库。" /> 的参数 "user"。
                          </>
                        ) : thought.text.includes('MFA') ? (
                          <>
                            我已通过旧版 VPN 门户发现一个潜在入口点。正在尝试使用已知的会话固定技术绕过 <ConceptTooltip text="MFA" concept="Multi-Factor Authentication" explanation="多因素身份验证，要求用户提供两种或多种验证因素才能访问资源。" />。
                          </>
                        ) : thought.text.includes('SSRF') ? (
                          <>
                            正在审查后端 API 代码。发现 `/v2/internal/config` 接口存在 <ConceptTooltip text="SSRF" concept="Server-Side Request Forgery" explanation="服务端请求伪造，攻击者诱使服务器向内网或外部服务器发起恶意请求。" /> 风险。
                          </>
                        ) : (
                          `"${thought.text}"`
                        )}
                      </p>
                    </div>
                  ))}
                </div>
              </div>
            </Panel>

            {/* Attack Path Visualization */}
            <Panel title="攻击路径可视化" className="col-span-5 row-span-4" icon={Network}>
              <div className="h-full flex flex-col items-center justify-center relative">
                <div className="absolute inset-0 opacity-10 pointer-events-none" style={{ backgroundImage: 'radial-gradient(#00ff00 1px, transparent 1px)', backgroundSize: '20px 20px' }} />
                
                {/* Mock Graph with Arrowheads */}
                <div className="flex flex-col items-center gap-12 z-10 w-full max-w-md">
                  <div className="flex flex-col items-center gap-2">
                    <motion.div 
                      whileHover={{ scale: 1.1 }}
                      className="w-14 h-14 rounded-full border-2 border-cyber-accent flex items-center justify-center bg-cyber-accent/10 neon-border cursor-pointer"
                    >
                      <Search size={20} className="text-cyber-accent" />
                    </motion.div>
                    <span className="text-[10px] font-bold text-cyber-accent uppercase tracking-tighter">信息侦察</span>
                  </div>
                  
                  <div className="relative flex flex-col items-center w-full">
                    <div className="h-12 w-0.5 bg-cyber-accent shadow-[0_0_5px_#00ff00]" />
                    <div className="absolute bottom-0 -mb-1">
                      <svg width="10" height="10" viewBox="0 0 12 12" className="fill-cyber-accent">
                        <path d="M6 12L0 0H12L6 12Z" />
                      </svg>
                    </div>
                  </div>
                  
                  <div className="flex justify-between w-full px-8 relative">
                    {/* Horizontal connector with arrows */}
                    <div className="absolute top-7 left-1/2 -translate-x-1/2 w-1/2 h-0.5 bg-cyber-accent/30 flex justify-between items-center">
                      <svg width="8" height="8" viewBox="0 0 8 8" className="fill-cyber-accent -ml-1">
                        <path d="M0 4L8 0V8L0 4Z" />
                      </svg>
                      <svg width="8" height="8" viewBox="0 0 8 8" className="fill-red-500 -mr-1">
                        <path d="M8 4L0 0V8L8 4Z" />
                      </svg>
                    </div>
                    
                    <div className="flex flex-col items-center gap-2">
                      <motion.div 
                        whileHover={{ scale: 1.1 }}
                        className="w-14 h-14 rounded-full border-2 border-cyber-accent flex items-center justify-center bg-cyber-accent/10 neon-border cursor-pointer relative"
                      >
                        <Zap size={20} className="text-cyber-accent" />
                        <div className="absolute -top-1 -right-1 w-4 h-4 bg-cyber-accent rounded-full flex items-center justify-center text-[8px] font-bold text-black">3</div>
                      </motion.div>
                      <span className="text-[10px] font-bold text-cyber-accent uppercase tracking-tighter">漏洞利用</span>
                    </div>
 
                    <div className="flex flex-col items-center gap-2">
                      <motion.div 
                        whileHover={{ scale: 1.1 }}
                        className="w-14 h-14 rounded-full border-2 border-red-500 flex items-center justify-center bg-red-500/10 shadow-[0_0_15px_rgba(239,68,68,0.4)] border-red-500/50 cursor-pointer"
                      >
                        <AlertTriangle size={20} className="text-red-500" />
                      </motion.div>
                      <span className="text-[10px] font-bold text-red-500 uppercase tracking-tighter">关键漏洞</span>
                    </div>
                  </div>
                  
                  <div className="relative flex flex-col items-center w-full">
                    <div className="h-12 w-0.5 bg-white/10" />
                    <div className="absolute bottom-0 -mb-1">
                      <svg width="10" height="10" viewBox="0 0 12 12" className="fill-white/10">
                        <path d="M6 12L0 0H12L6 12Z" />
                      </svg>
                    </div>
                  </div>
                  
                  <div className="flex flex-col items-center gap-2">
                    <motion.div 
                      whileHover={{ scale: 1.1 }}
                      className="w-14 h-14 rounded-full border-2 border-cyber-muted flex items-center justify-center bg-white/5 cursor-pointer"
                    >
                      <CheckCircle2 size={20} className="text-cyber-muted" />
                    </motion.div>
                    <span className="text-[10px] font-bold text-cyber-muted uppercase tracking-tighter">后渗透</span>
                  </div>
                </div>
              </div>
            </Panel>

            {/* Risk Analysis */}
            <Panel title="风险矩阵分析" className="col-span-3 row-span-2" icon={AlertTriangle}>
              <div className="h-full flex flex-col gap-4">
                <div className="flex-1 min-h-[100px] relative">
                  <ResponsiveContainer width="100%" height="100%">
                    <PieChart>
                      <Pie
                        data={RISK_DATA}
                        innerRadius={35}
                        outerRadius={50}
                        paddingAngle={5}
                        dataKey="value"
                        stroke="none"
                      >
                        {RISK_DATA.map((entry, index) => (
                          <Cell key={`cell-${index}`} fill={entry.color} />
                        ))}
                      </Pie>
                      <Tooltip 
                        contentStyle={{ backgroundColor: '#0a0a0a', border: '1px solid #1a1a1a', fontSize: '10px', borderRadius: '4px' }}
                        itemStyle={{ color: '#fff' }}
                      />
                    </PieChart>
                  </ResponsiveContainer>
                  <div className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none">
                    <span className="text-xs font-bold text-white">3</span>
                    <span className="text-[7px] text-cyber-muted uppercase">总漏洞</span>
                  </div>
                </div>
                <div className="overflow-auto max-h-[120px] custom-scrollbar">
                  <table className="w-full text-[9px] text-left border-collapse">
                    <thead>
                      <tr className="text-cyber-muted border-b border-cyber-border">
                        <th className="pb-2 font-bold uppercase tracking-tighter">目标主机</th>
                        <th className="pb-2 font-bold uppercase tracking-tighter">风险等级</th>
                        <th className="pb-2 font-bold uppercase tracking-tighter text-right">CVSS</th>
                      </tr>
                    </thead>
                    <tbody className="divide-y divide-white/5">
                      {MOCK_EVIDENCE.map((ev) => (
                        <tr key={ev.id} className="hover:bg-white/5 transition-colors group">
                          <td className="py-2 font-mono text-cyber-accent group-hover:text-white transition-colors">{ev.host}</td>
                          <td className="py-2">
                            <div className="flex items-center gap-1.5">
                              <div className={cn(
                                "w-1 h-1 rounded-full",
                                ev.severity === 'Critical' ? "bg-red-500" : "bg-orange-500"
                              )} />
                              <span className={cn(
                                "font-bold",
                                ev.severity === 'Critical' ? "text-red-500" : "text-orange-500"
                              )}>{ev.severity === 'Critical' ? '严重' : '高危'}</span>
                            </div>
                          </td>
                          <td className="py-2 text-right font-mono text-cyber-muted">{ev.cvss}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            </Panel>

            {/* Evidence Gallery */}
            <Panel title="证据与截图画廊" className="col-span-3 row-span-2" icon={ImageIcon}>
              <div className="flex flex-col h-full gap-3">
                <div className="flex-1 overflow-x-auto flex gap-4 pb-2 scrollbar-thin scrollbar-thumb-cyber-accent/20">
                  {MOCK_ARTIFACTS.map((art) => (
                    <div key={art.id} className="group relative rounded-lg overflow-hidden border border-cyber-border w-56 shrink-0 aspect-[16/10] cursor-pointer bg-black/40">
                      <img src={art.url} alt={art.title} className="w-full h-full object-cover grayscale group-hover:grayscale-0 transition-all duration-700 scale-105 group-hover:scale-100" referrerPolicy="no-referrer" />
                      <div className="absolute inset-0 bg-gradient-to-t from-black/95 via-black/40 to-transparent opacity-0 group-hover:opacity-100 transition-all duration-500 flex flex-col justify-end p-3">
                        <div className="text-[10px] font-bold uppercase tracking-wider text-cyber-accent mb-1">{art.title}</div>
                        <div className="flex items-center justify-between">
                          <div className="text-[8px] text-cyber-muted flex items-center gap-1">
                            <Clock size={10} /> {art.timestamp}
                          </div>
                          <div className="flex gap-1.5">
                            <button className="p-1 rounded bg-cyber-accent/20 text-cyber-accent hover:bg-cyber-accent hover:text-black transition-colors">
                              <Eye size={10} />
                            </button>
                            <button className="p-1 rounded bg-white/10 text-white hover:bg-white/20 transition-colors">
                              <Download size={10} />
                            </button>
                          </div>
                        </div>
                      </div>
                      <div className="absolute top-2 left-2 px-1.5 py-0.5 bg-black/60 backdrop-blur-md rounded text-[7px] text-cyber-accent border border-cyber-accent/30 font-mono uppercase">
                        {art.type}
                      </div>
                    </div>
                  ))}
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <button className="py-2 border border-cyber-border rounded-md text-[10px] text-cyber-muted hover:text-cyber-accent hover:border-cyber-accent transition-all flex items-center justify-center gap-2 bg-white/5">
                    <Download size={12} /> 导出全部证据
                  </button>
                  <button className="py-2 border border-cyber-border rounded-md text-[10px] text-cyber-muted hover:text-cyber-accent hover:border-cyber-accent transition-all flex items-center justify-center gap-2 bg-white/5">
                    <ExternalLink size={12} /> 深度分析
                  </button>
                </div>
              </div>
            </Panel>

            {/* Activity Chart */}
            <Panel title="智能体活动频率" className="col-span-3 row-span-2" icon={BarChart3}>
              <div className="h-full flex flex-col">
                <div className="flex-1">
                  <ResponsiveContainer width="100%" height="100%">
                    <AreaChart data={ACTIVITY_DATA}>
                      <defs>
                        <linearGradient id="colorActions" x1="0" y1="0" x2="0" y2="1">
                          <stop offset="5%" stopColor="#00ff00" stopOpacity={0.3}/>
                          <stop offset="95%" stopColor="#00ff00" stopOpacity={0}/>
                        </linearGradient>
                      </defs>
                      <Area type="monotone" dataKey="actions" stroke="#00ff00" fillOpacity={1} fill="url(#colorActions)" />
                      <Tooltip 
                        contentStyle={{ backgroundColor: '#0a0a0a', border: '1px solid #1a1a1a', fontSize: '10px', borderRadius: '4px' }}
                        itemStyle={{ color: '#00ff00' }}
                      />
                    </AreaChart>
                  </ResponsiveContainer>
                </div>
                <div className="flex justify-between text-[8px] text-cyber-muted font-mono mt-1">
                  <span>09:00</span>
                  <span>10:00</span>
                </div>
              </div>
            </Panel>

            {/* Real-time Timeline */}
            <Panel title="实时操作流水" className="col-span-6 row-span-2" icon={Activity}>
              <div className="space-y-3">
                {MOCK_ACTIONS.map((action) => (
                  <div key={action.id} className="flex items-center gap-4 text-[10px] group hover:bg-white/5 p-1 rounded transition-colors">
                    <span className="text-cyber-muted font-mono w-14">{action.timestamp}</span>
                    <div className={cn(
                      "w-2 h-2 rounded-full shrink-0",
                      action.status === 'success' ? "bg-cyber-accent shadow-[0_0_5px_#00ff00]" : "bg-cyber-accent/50 animate-pulse"
                    )} />
                    <span className="text-cyber-accent uppercase font-bold w-12 tracking-tighter">{action.type}</span>
                    <span className="flex-1 text-cyber-muted group-hover:text-cyber-text transition-colors truncate font-mono">
                      <span className="text-cyber-accent/50 mr-1">$</span>
                      {action.command}
                    </span>
                    <span className={cn(
                      "px-1.5 py-0.5 rounded text-[8px] font-bold uppercase",
                      action.status === 'success' ? "bg-cyber-accent/10 text-cyber-accent" : "bg-white/5 text-cyber-muted"
                    )}>
                      {action.status === 'success' ? '完成' : '运行中'}
                    </span>
                  </div>
                ))}
              </div>
            </Panel>

            {/* PoC Sandbox & Vulnerability List */}
            <div className="col-span-3 row-span-2 grid grid-rows-2 gap-4">
              <Panel title="PoC 验证沙箱" icon={Terminal} badge={sandboxStatus === 'idle' ? '待命' : sandboxStatus === 'running' ? '运行中' : '成功'}>
                <div className="flex flex-col h-full gap-2">
                  <div className="flex-1 bg-black/40 rounded border border-cyber-border p-2 font-mono text-[9px] overflow-auto">
                    <div className="text-cyber-accent"># 正在验证 CVE-2024-1234</div>
                    <div className="text-cyber-muted">target: 192.168.1.10</div>
                    <div className="text-cyber-muted">payload: log4j-rce-v2.py</div>
                    {sandboxStatus === 'running' && (
                      <div className="flex items-center gap-2 mt-2 text-cyber-accent animate-pulse">
                        <Loader2 size={10} className="animate-spin" />
                        <span>正在执行利用脚本...</span>
                      </div>
                    )}
                    {sandboxStatus === 'success' && (
                      <div className="mt-2 space-y-1">
                        <div className="text-cyber-accent flex items-center gap-1">
                          <Check size={10} /> 利用成功！已获得反弹 Shell。
                        </div>
                        <div className="text-blue-400">$ whoami</div>
                        <div className="text-white">root</div>
                      </div>
                    )}
                  </div>
                  <div className="flex gap-2">
                    <button 
                      onClick={runSandbox}
                      disabled={sandboxStatus !== 'idle'}
                      className={cn(
                        "flex-1 py-1.5 rounded text-[9px] font-bold flex items-center justify-center gap-1 transition-all",
                        sandboxStatus === 'idle' ? "bg-cyber-accent text-black hover:brightness-110" : "bg-white/5 text-cyber-muted cursor-not-allowed"
                      )}
                    >
                      {sandboxStatus === 'running' ? <Loader2 size={10} className="animate-spin" /> : <Play size={10} fill="currentColor" />}
                      运行沙箱
                    </button>
                    <button 
                      disabled={sandboxStatus !== 'success'}
                      className={cn(
                        "flex-1 py-1.5 rounded text-[9px] font-bold flex items-center justify-center gap-1 transition-all",
                        sandboxStatus === 'success' ? "bg-blue-600 text-white hover:bg-blue-500" : "bg-white/5 text-cyber-muted cursor-not-allowed"
                      )}
                    >
                      <Zap size={10} fill="currentColor" /> 应用修复
                    </button>
                  </div>
                </div>
              </Panel>

              <Panel title="关键发现与报告" icon={Lock}>
                <div className="flex flex-col h-full gap-2">
                  <div className="flex-1 space-y-2 overflow-auto">
                    {MOCK_EVIDENCE.map((ev) => (
                      <div key={ev.id} className="p-2 bg-white/5 border border-cyber-border rounded hover:bg-white/10 transition-colors cursor-pointer group">
                        <div className="flex justify-between items-start mb-1">
                          <div className="flex items-center gap-1.5">
                            <div className={cn(
                              "w-1.5 h-1.5 rounded-full",
                              ev.severity === 'Critical' ? "bg-red-500 shadow-[0_0_5px_#ef4444]" : "bg-orange-500"
                            )} />
                            <span className="text-[10px] font-bold text-cyber-accent">{ev.host}</span>
                          </div>
                          <span className={cn(
                            "text-[8px] px-1 rounded font-bold text-white",
                            ev.severity === 'Critical' ? "bg-red-500" : "bg-orange-500"
                          )}>
                            {ev.severity === 'Critical' ? '严重' : '高危'}
                          </span>
                        </div>
                        <div className="text-[9px] text-cyber-muted group-hover:text-cyber-text transition-colors truncate font-mono">
                          {ev.description}
                        </div>
                      </div>
                    ))}
                    
                    {showReport && (
                      <motion.div
                        initial={{ opacity: 0, y: 10 }}
                        animate={{ opacity: 1, y: 0 }}
                        className="mt-4 p-3 bg-cyber-accent/5 border border-cyber-accent/20 rounded-lg relative overflow-hidden"
                      >
                        <div className="absolute top-0 right-0 w-16 h-16 bg-cyber-accent/5 -rotate-45 translate-x-8 -translate-y-8" />
                        
                        <div className="text-[10px] font-bold text-cyber-accent mb-2 flex items-center gap-2">
                          <FileText size={12} /> 渗透测试报告已生成
                        </div>
                        
                        <div className="text-[9px] text-cyber-muted mb-3 leading-relaxed">
                          基于当前扫描结果，系统已自动生成详细报告。共发现 <span className="text-red-500 font-bold">2</span> 个高危漏洞，建议立即采取修复措施。
                        </div>
                        
                        {/* Risk Matrix Summary */}
                        <div className="grid grid-cols-4 gap-2 mb-4">
                          {[
                            { label: '严重', count: 1, color: 'bg-red-500' },
                            { label: '高危', count: 1, color: 'bg-orange-500' },
                            { label: '中危', count: 1, color: 'bg-yellow-500' },
                            { label: '低危', count: 0, color: 'bg-emerald-500' },
                          ].map((risk, idx) => (
                            <div key={idx} className="flex flex-col items-center p-1.5 bg-black/40 rounded border border-white/5 hover:border-cyber-accent/30 transition-colors">
                              <div className={`w-1 h-1 rounded-full ${risk.color} mb-1`} />
                              <div className="text-[7px] text-cyber-muted uppercase tracking-tighter">{risk.label}</div>
                              <div className="text-[11px] font-mono font-bold text-white">{risk.count}</div>
                            </div>
                          ))}
                        </div>
 
                        <div className="flex gap-2">
                          <button className="flex-1 py-2 bg-cyber-accent text-black font-bold rounded text-[9px] flex items-center justify-center gap-2 hover:brightness-110 transition-all shadow-[0_0_10px_rgba(0,255,0,0.2)]">
                            <FileDown size={12} /> 下载 PDF
                          </button>
                          <button className="p-2 bg-white/5 border border-cyber-border rounded text-cyber-muted hover:text-cyber-accent transition-all">
                            <Eye size={12} />
                          </button>
                        </div>
                      </motion.div>
                    )}
                  </div>
                </div>
              </Panel>
            </div>
          </div>
        </div>
      </main>

      {/* Footer Status Bar */}
      <footer className="h-8 border-t border-cyber-border bg-cyber-panel flex items-center px-4 justify-between text-[10px] text-cyber-muted uppercase tracking-widest font-bold">
        <div className="flex items-center gap-4">
          <div className="flex items-center gap-1.5">
            <div className="w-1.5 h-1.5 rounded-full bg-cyber-accent shadow-[0_0_5px_#00ff00]" />
            <span>系统在线</span>
          </div>
          <div className="flex items-center gap-1.5">
            <div className="w-1.5 h-1.5 rounded-full bg-cyber-accent" />
            <span>数据库已连接</span>
          </div>
        </div>
        <div className="flex items-center gap-6">
          <div className="flex items-center gap-2">
            <span className="text-cyber-muted">延迟:</span>
            <span className="text-cyber-accent font-mono">24ms</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="text-cyber-muted">版本:</span>
            <span className="text-cyber-accent font-mono">v2.4.0-stable</span>
          </div>
          <div className="text-cyber-muted">© 2026 PENTAGI CYBER OPS</div>
        </div>
      </footer>
    </div>
  );
}
