<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CyberStrikeAI</title>
    <link rel="icon" type="image/png" href="/static/logo.png">
    <link rel="shortcut icon" type="image/png" href="/static/favicon.ico">
    <link rel="stylesheet" href="/static/css/style.css">
    <link rel="stylesheet" href="/static/css/c2.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.19.0/css/xterm.css">
</head>
<body>
    <div id="login-overlay" class="login-overlay" style="display: none;">
        <div class="login-card">
            <div class="login-brand">
                <img src="/static/logo.png" alt="" class="login-brand-logo" width="56" height="56">
                <h2 class="login-title">
                    <span data-i18n="login.titlePrefix">登录</span>
                    <span class="brand-wordmark brand-wordmark--sm" aria-label="CyberStrikeAI">
                        <span class="brand-wordmark__core">CyberStrike</span><span class="brand-wordmark__ai">AI</span>
                    </span>
                </h2>
                <p class="login-subtitle" data-i18n="login.subtitle">请输入配置中的访问密码</p>
            </div>
            <form id="login-form" class="login-form">
                <div class="form-group">
                    <label for="login-password" data-i18n="login.passwordLabel">密码</label>
                    <input type="password" id="login-password" placeholder="输入登录密码" required autocomplete="current-password" data-i18n="login.passwordPlaceholder" data-i18n-attr="placeholder" />
                </div>
                <div id="login-error" class="login-error" role="alert" style="display: none;"></div>
                <button type="submit" class="btn-primary login-submit">
                    <span data-i18n="login.submit">登录</span>
                </button>
            </form>
        </div>
    </div>

    <div class="container">
        <header>
            <div class="header-content">
                <div class="logo header-logo-link" onclick="switchPage('dashboard')" role="button" data-i18n="header.backToDashboard" data-i18n-attr="title" data-i18n-skip-text="true" title="返回仪表盘">
                    <img src="/static/logo.png" alt="CyberStrikeAI Logo" class="brand-logo" width="36" height="36">
                    <h1 class="brand-wordmark brand-wordmark--lg">
                        <span class="brand-wordmark__core">CyberStrike</span><span class="brand-wordmark__ai">AI</span>
                    </h1>
                    <span class="version-badge" data-i18n="header.version" data-i18n-attr="title" data-i18n-skip-text="true" title="当前版本">{{.Version}}</span>
                </div>
                <div class="header-right">
                    <div class="header-actions">
                        <button class="openapi-doc-btn" onclick="window.open('/api-docs', '_blank')" data-i18n="header.apiDocs" data-i18n-attr="title" data-i18n-skip-text="true" title="API 文档">
                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                <polyline points="14 2 14 8 20 8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                <path d="M16 13H8M16 17H8M10 9H8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                            <span data-i18n="header.apiDocs">API 文档</span>
                        </button>
                                        <button class="openapi-doc-btn" onclick="window.open('https://github.com/Ed1s0nZ/CyberStrikeAI', '_blank')" data-i18n="header.github" data-i18n-attr="title" data-i18n-skip-text="true" title="GitHub">
                                            <svg width="16" height="16" viewBox="0 0 98 96" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
                                                <path d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"/>
                                            </svg>
                                            <span data-i18n="header.github">GitHub</span>
                                        </button>
                        <div class="lang-switcher">
                            <button class="btn-secondary lang-switcher-btn" onclick="toggleLangDropdown()" data-i18n="header.language" data-i18n-attr="title" data-i18n-skip-text="true" title="界面语言">
                                <span class="lang-switcher-icon">🌐</span>
                                <span id="current-lang-label">中文</span>
                            </button>
                            <div id="lang-dropdown" class="lang-dropdown" style="display: none;">
                                <div class="lang-option" data-lang="zh-CN" onclick="onLanguageSelect('zh-CN')">中文</div>
                                <div class="lang-option" data-lang="en-US" onclick="onLanguageSelect('en-US')">English</div>
                            </div>
                        </div>
                        <div class="notification-menu-container">
                            <button class="notification-btn" id="notification-bell-btn" onclick="toggleNotificationDropdown()" data-i18n="notifications.title" data-i18n-attr="title" data-i18n-skip-text="true" title="事件通知">
                                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    <path d="M13.73 21a2 2 0 0 1-3.46 0" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                                <span class="notification-badge" id="notification-badge" style="display: none;">0</span>
                            </button>
                            <div id="notification-dropdown" class="notification-dropdown" style="display: none;">
                                <div class="notification-dropdown-header">
                                    <span id="notification-dropdown-title" data-i18n="notifications.title">事件通知</span>
                                    <button class="notification-mark-read-btn" id="notification-mark-all-read-btn" type="button" onclick="markAllNotificationsSeen()" data-i18n="notifications.markAllRead">标记已读</button>
                                </div>
                                <div id="notification-list" class="notification-list">
                                    <div class="notification-empty" data-i18n="notifications.empty">暂无新事件</div>
                                </div>
                            </div>
                        </div>
                        <div class="user-menu-container">
                            <button class="user-avatar-btn" onclick="toggleUserMenu()" data-i18n="header.userMenu" data-i18n-attr="title" data-i18n-skip-text="true" title="用户菜单">
                                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    <circle cx="12" cy="7" r="4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                </svg>
                            </button>
                            <div id="user-menu-dropdown" class="user-menu-dropdown" style="display: none;">
                                <div class="user-menu-item" onclick="logout()">
                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                        <polyline points="16 17 21 12 16 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                        <line x1="21" y1="12" x2="9" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    </svg>
                                    <span data-i18n="header.logout">退出登录</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </header>

        <div class="main-layout">
            <!-- 主侧边栏 -->
            <aside class="main-sidebar" id="main-sidebar">
                <div class="sidebar-collapse-btn" onclick="toggleSidebar()" data-i18n="header.toggleSidebar" data-i18n-attr="title" data-i18n-skip-text="true" title="折叠/展开侧边栏">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M15 18l-6-6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    </svg>
                </div>
                <nav class="main-sidebar-nav">
                    <div class="nav-item" data-page="dashboard">
                        <div class="nav-item-content" data-title="仪表盘" onclick="switchPage('dashboard')" data-i18n="nav.dashboard" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <rect x="3" y="3" width="7" height="9"></rect>
                                <rect x="14" y="3" width="7" height="5"></rect>
                                <rect x="14" y="12" width="7" height="9"></rect>
                                <rect x="3" y="16" width="7" height="5"></rect>
                            </svg>
                            <span data-i18n="nav.dashboard">仪表盘</span>
                        </div>
                    </div>
                    <div class="nav-item" data-page="chat">
                        <div class="nav-item-content" data-title="对话" onclick="switchPage('chat')" data-i18n="nav.chat" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
                            </svg>
                            <span data-i18n="nav.chat">对话</span>
                        </div>
                    </div>
                    <div class="nav-item" data-page="hitl">
                        <div class="nav-item-content" data-title="人机协同" onclick="switchPage('hitl')">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path>
                                <circle cx="9" cy="7" r="4"></circle>
                                <polyline points="16 11 18 13 22 9"></polyline>
                            </svg>
                            <span data-i18n="nav.hitl">人机协同</span>
                        </div>
                    </div>
                    <div class="nav-item" data-page="info-collect">
                        <div class="nav-item-content" data-title="信息收集" onclick="switchPage('info-collect')" data-i18n="nav.infoCollect" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <circle cx="11" cy="11" r="8"></circle>
                                <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
                            </svg>
                            <span data-i18n="nav.infoCollect">信息收集</span>
                        </div>
                    </div>
                    <div class="nav-item" data-page="tasks">
                        <div class="nav-item-content" data-title="任务管理" onclick="switchPage('tasks')" data-i18n="nav.tasks" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M9 11l3 3L22 4"></path>
                                <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path>
                            </svg>
                            <span data-i18n="nav.tasks">任务管理</span>
                        </div>
                    </div>
                    <div class="nav-item" data-page="projects">
                        <div class="nav-item-content" data-title="项目管理" onclick="switchPage('projects')" data-i18n="nav.projects" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
                                <polyline points="2 17 12 22 22 17"></polyline>
                                <polyline points="2 12 12 17 22 12"></polyline>
                            </svg>
                            <span data-i18n="nav.projects">项目管理</span>
                        </div>
                    </div>
                    <div class="nav-item" data-page="vulnerabilities">
                        <div class="nav-item-content" data-title="漏洞管理" onclick="switchPage('vulnerabilities')" data-i18n="nav.vulnerabilities" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
                                <path d="M9 12l2 2 4-4"></path>
                            </svg>
                            <span data-i18n="nav.vulnerabilities">漏洞管理</span>
                        </div>
                    </div>
                    <div class="nav-item" data-page="chat-files">
                        <div class="nav-item-content" data-title="文件管理" onclick="switchPage('chat-files')" data-i18n="nav.chatFiles" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
                            </svg>
                            <span data-i18n="nav.chatFiles">文件管理</span>
                        </div>
                    </div>
                    <div class="nav-item" data-page="webshell">
                        <div class="nav-item-content" data-title="WebShell管理" onclick="switchPage('webshell')" data-i18n="nav.webshell" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <polyline points="4 17 10 11 4 5"></polyline>
                                <line x1="12" y1="19" x2="20" y2="19"></line>
                            </svg>
                            <span data-i18n="nav.webshell">WebShell管理</span>
                        </div>
                    </div>
                    <!-- C2 侧栏入口（带子菜单） -->
                    <div class="nav-item nav-item-has-submenu" data-page="c2" id="nav-c2">
                        <div class="nav-item-content" data-title="C2" onclick="window.toggleSubmenu('c2')" data-i18n="nav.c2" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                                <path d="M4.9 19.1C1 15.2 1 8.8 4.9 4.9"></path>
                                <path d="M7.8 16.2c-2.3-2.3-2.3-6.1 0-8.5"></path>
                                <circle cx="12" cy="12" r="2"></circle>
                                <path d="M16.2 7.8c2.3 2.3 2.3 6.1 0 8.5"></path>
                                <path d="M19.1 4.9C23 8.8 23 15.2 19.1 19"></path>
                            </svg>
                            <span data-i18n="nav.c2">C2</span>
                            <svg class="submenu-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <div class="nav-submenu" id="submenu-c2">
                            <div class="nav-submenu-item" data-page="c2" onclick="switchPage('c2')" data-i18n="nav.c2Manage">C2 管理</div>
                            <div class="nav-submenu-item" data-page="c2-listeners" onclick="switchPage('c2-listeners')" data-i18n="nav.c2Listeners">监听器</div>
                            <div class="nav-submenu-item" data-page="c2-sessions" onclick="switchPage('c2-sessions')" data-i18n="nav.c2Sessions">会话</div>
                            <div class="nav-submenu-item" data-page="c2-tasks" onclick="switchPage('c2-tasks')" data-i18n="nav.c2Tasks">任务</div>
                            <div class="nav-submenu-item" data-page="c2-payloads" onclick="switchPage('c2-payloads')" data-i18n="nav.c2Payloads">Payload</div>
                            <div class="nav-submenu-item" data-page="c2-events" onclick="switchPage('c2-events')" data-i18n="nav.c2Events">事件</div>
                            <div class="nav-submenu-item" data-page="c2-profiles" onclick="switchPage('c2-profiles')" data-i18n="nav.c2Profiles">流量伪装</div>
                        </div>
                    </div>
                    <div class="nav-item nav-item-has-submenu" data-page="mcp">
                        <div class="nav-item-content" data-title="MCP" onclick="window.toggleSubmenu('mcp')" data-i18n="nav.mcp" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path>
                            </svg>
                            <span data-i18n="nav.mcp">MCP</span>
                            <svg class="submenu-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <div class="nav-submenu">
                            <div class="nav-submenu-item" data-page="mcp-monitor" onclick="switchPage('mcp-monitor')">
                                <span data-i18n="nav.mcpMonitor">MCP状态监控</span>
                            </div>
                            <div class="nav-submenu-item" data-page="mcp-management" onclick="switchPage('mcp-management')">
                                <span data-i18n="nav.mcpManagement">MCP管理</span>
                            </div>
                        </div>
                    </div>
                    <div class="nav-item nav-item-has-submenu" data-page="knowledge">
                        <div class="nav-item-content" data-title="知识" onclick="window.toggleSubmenu('knowledge')" data-i18n="nav.knowledge" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path>
                                <path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path>
                            </svg>
                            <span data-i18n="nav.knowledge">知识</span>
                            <svg class="submenu-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <div class="nav-submenu">
                            <div class="nav-submenu-item" data-page="knowledge-retrieval-logs" onclick="switchPage('knowledge-retrieval-logs')">
                                <span data-i18n="nav.knowledgeRetrievalLogs">检索历史</span>
                            </div>
                            <div class="nav-submenu-item" data-page="knowledge-management" onclick="switchPage('knowledge-management')">
                                <span data-i18n="nav.knowledgeManagement">知识管理</span>
                            </div>
                        </div>
                    </div>
                    <div class="nav-item nav-item-has-submenu" data-page="skills">
                        <div class="nav-item-content" data-title="Skills" onclick="window.toggleSubmenu('skills')" data-i18n="nav.skills" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path>
                                <polyline points="14 2 14 8 20 8"></polyline>
                                <line x1="16" y1="13" x2="8" y2="13"></line>
                                <line x1="16" y1="17" x2="8" y2="17"></line>
                                <polyline points="10 9 9 9 8 9"></polyline>
                            </svg>
                            <span data-i18n="nav.skills">Skills</span>
                            <svg class="submenu-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <div class="nav-submenu">
                            <div class="nav-submenu-item" data-page="skills-monitor" onclick="switchPage('skills-monitor')">
                                <span data-i18n="nav.skillsMonitor">Skills状态监控</span>
                            </div>
                            <div class="nav-submenu-item" data-page="skills-management" onclick="switchPage('skills-management')">
                                <span data-i18n="nav.skillsManagement">Skills管理</span>
                            </div>
                        </div>
                    </div>
                    <div class="nav-item nav-item-has-submenu" data-page="agents">
                        <div class="nav-item-content" data-title="Agents" onclick="window.toggleSubmenu('agents')" data-i18n="nav.agents" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <polygon points="12 2 2 7 12 12 22 7 12 2"></polygon>
                                <polyline points="2 17 12 22 22 17"></polyline>
                                <polyline points="2 12 12 17 22 12"></polyline>
                            </svg>
                            <span data-i18n="nav.agents">Agents</span>
                            <svg class="submenu-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <div class="nav-submenu">
                            <div class="nav-submenu-item" data-page="agents-management" onclick="switchPage('agents-management')">
                                <span data-i18n="nav.agentsManagement">Agent管理</span>
                            </div>
                        </div>
                    </div>
                    <div class="nav-item nav-item-has-submenu" data-page="roles">
                        <div class="nav-item-content" data-title="角色" onclick="window.toggleSubmenu('roles')" data-i18n="nav.roles" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
                                <circle cx="9" cy="7" r="4"></circle>
                                <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
                                <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
                            </svg>
                            <span data-i18n="nav.roles">角色</span>
                            <svg class="submenu-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </div>
                        <div class="nav-submenu">
                            <div class="nav-submenu-item" data-page="roles-management" onclick="switchPage('roles-management')">
                                <span data-i18n="nav.rolesManagement">角色管理</span>
                            </div>
                        </div>
                    </div>
                    <div class="nav-item" data-page="settings">
                        <div class="nav-item-content" data-title="系统设置" onclick="switchPage('settings')" data-i18n="nav.settings" data-i18n-attr="data-title" data-i18n-skip-text="true">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <circle cx="12" cy="12" r="3"></circle>
                                <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
                            </svg>
                            <span data-i18n="nav.settings">系统设置</span>
                        </div>
                    </div>
                </nav>
            </aside>

            <!-- 内容区域 -->
            <div class="content-area">
                <!-- 仪表盘页面 -->
                <div id="page-dashboard" class="page active">
                    <div class="dashboard-page">
                        <div class="page-header">
                            <h2 data-i18n="dashboard.title">仪表盘</h2>
                            <div class="page-header-actions">
                                <span class="dashboard-last-updated" id="dashboard-last-updated" aria-live="polite">
                                    <svg class="dashboard-last-updated-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
                                    <span data-i18n="dashboard.lastUpdated">上次更新</span>
                                    <span class="dashboard-last-updated-time" id="dashboard-last-updated-time">-</span>
                                    <span class="dashboard-last-updated-stale" id="dashboard-last-updated-stale" hidden data-i18n="dashboard.dataStale" data-i18n-attr="title" title="数据可能已过期">
                                        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
                                    </span>
                                </span>
                                <button class="btn-secondary" onclick="refreshDashboard()" data-i18n="dashboard.refreshData" data-i18n-attr="title" title="刷新数据"><span data-i18n="common.refresh">刷新</span></button>
                            </div>
                        </div>
                        <div class="dashboard-content">
                            <!-- 关键提醒条（仅当存在严重风险时渲染，默认 hidden）；右侧 × 可在 session 内忽略 -->
                            <div class="dashboard-alert-banner" id="dashboard-alert-banner" hidden>
                                <span class="dashboard-alert-icon" aria-hidden="true">
                                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
                                </span>
                                <div class="dashboard-alert-content">
                                    <div class="dashboard-alert-title" id="dashboard-alert-title" data-i18n="dashboard.alertTitle">需要关注</div>
                                    <div class="dashboard-alert-desc" id="dashboard-alert-desc"></div>
                                </div>
                                <div class="dashboard-alert-actions" id="dashboard-alert-actions"></div>
                                <button type="button" class="dashboard-alert-close" id="dashboard-alert-close" data-i18n="dashboard.alertDismiss" data-i18n-attr="title" data-i18n-skip-text="true" title="忽略此提醒（仅本次会话）" aria-label="dismiss">
                                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                                </button>
                            </div>
                            <!-- 第一行：核心 KPI（关键指标置顶 + 副标徽章承载次级信息） -->
                            <div class="dashboard-kpi-row" id="dashboard-cards">
                                <div class="dashboard-kpi-card" role="button" tabindex="0" onclick="switchPage('tasks')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('tasks'); }" data-i18n="dashboard.clickToViewTasks" data-i18n-attr="title" title="点击查看任务管理">
                                    <div class="dashboard-kpi-head">
                                        <div class="dashboard-kpi-label" data-i18n="dashboard.runningTasks">运行中任务</div>
                                        <span class="dashboard-kpi-icon dashboard-kpi-icon-tasks" aria-hidden="true"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v4"/><path d="M12 18v4"/><path d="M4.93 4.93l2.83 2.83"/><path d="M16.24 16.24l2.83 2.83"/><path d="M2 12h4"/><path d="M18 12h4"/><path d="M4.93 19.07l2.83-2.83"/><path d="M16.24 7.76l2.83-2.83"/></svg></span>
                                    </div>
                                    <div class="dashboard-kpi-value" id="dashboard-running-tasks">-</div>
                                    <div class="dashboard-kpi-sub" id="dashboard-kpi-tasks-sub">
                                        <span class="dashboard-kpi-sub-text" id="dashboard-kpi-tasks-sub-text">-</span>
                                    </div>
                                </div>
                                <div class="dashboard-kpi-card" role="button" tabindex="0" onclick="switchPage('vulnerabilities')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('vulnerabilities'); }" data-i18n="dashboard.clickToViewVuln" data-i18n-attr="title" title="点击查看漏洞管理">
                                    <div class="dashboard-kpi-head">
                                        <div class="dashboard-kpi-label" data-i18n="dashboard.vulnTotal">漏洞总数</div>
                                        <span class="dashboard-kpi-icon dashboard-kpi-icon-vuln" aria-hidden="true"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg></span>
                                    </div>
                                    <div class="dashboard-kpi-value" id="dashboard-vuln-total">-</div>
                                    <div class="dashboard-kpi-sub" id="dashboard-kpi-vuln-sub">
                                        <span class="dashboard-kpi-sub-badge dashboard-kpi-sub-badge-critical" id="dashboard-kpi-vuln-critical-badge" hidden>
                                            <span class="dashboard-kpi-sub-badge-dot"></span>
                                            <span data-i18n="dashboard.severityCritical">严重</span>
                                            <span id="dashboard-kpi-vuln-critical-count">0</span>
                                        </span>
                                        <span class="dashboard-kpi-sub-text" id="dashboard-kpi-vuln-sub-text" data-i18n="dashboard.allClear">暂无新增风险</span>
                                    </div>
                                </div>
                                <div class="dashboard-kpi-card" role="button" tabindex="0" onclick="switchPage('mcp-monitor')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('mcp-monitor'); }" data-i18n="dashboard.clickToViewMCP" data-i18n-attr="title" title="点击查看 MCP 监控">
                                    <div class="dashboard-kpi-head">
                                        <div class="dashboard-kpi-label" data-i18n="dashboard.toolCalls">工具调用次数</div>
                                        <span class="dashboard-kpi-icon dashboard-kpi-icon-calls" aria-hidden="true"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg></span>
                                    </div>
                                    <div class="dashboard-kpi-value" id="dashboard-kpi-tools-calls">-</div>
                                    <div class="dashboard-kpi-sub">
                                        <span class="dashboard-kpi-sub-text" id="dashboard-kpi-tools-sub-text">-</span>
                                    </div>
                                </div>
                                <div class="dashboard-kpi-card" role="button" tabindex="0" onclick="switchPage('mcp-monitor')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('mcp-monitor'); }" data-i18n="dashboard.clickToViewMCP" data-i18n-attr="title" title="点击查看 MCP 监控">
                                    <div class="dashboard-kpi-head">
                                        <div class="dashboard-kpi-label" data-i18n="dashboard.successRate">工具执行成功率</div>
                                        <span class="dashboard-kpi-icon dashboard-kpi-icon-rate" aria-hidden="true"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></span>
                                    </div>
                                    <div class="dashboard-kpi-value" id="dashboard-kpi-success-rate">-</div>
                                    <div class="dashboard-kpi-sub">
                                        <span class="dashboard-kpi-sub-text" id="dashboard-kpi-rate-sub-text" data-i18n="dashboard.healthyStatus">运行平稳</span>
                                    </div>
                                </div>
                            </div>
                            <!-- 两列主内容区 -->
                            <div class="dashboard-grid">
                                <div class="dashboard-main">
                                    <section class="dashboard-section dashboard-section-chart">
                                        <div class="dashboard-section-header">
                                            <h3 class="dashboard-section-title" data-i18n="dashboard.severityDistribution">漏洞严重程度分布</h3>
                                            <a class="dashboard-section-link" onclick="switchPage('vulnerabilities')" data-i18n="dashboard.viewAll">查看全部 →</a>
                                        </div>
                                        <div class="dashboard-severity-wrap">
                                            <!-- 风险概览卡：填充 donut 左侧留白；提供「结论性」洞察（风险等级/加权分/待处理计数/最新时间），
                                                 与右侧 legend 的「明细」形成互补，避免和下方「最近漏洞」列表重复 -->
                                            <aside class="dashboard-severity-insights" aria-label="风险概览">
                                                <div class="dashboard-severity-insight-risk" data-level="safe">
                                                    <div class="dashboard-severity-insight-head">
                                                        <span class="dashboard-severity-insight-label" data-i18n="dashboard.riskLevel">风险等级</span>
                                                        <span class="dashboard-severity-insight-risk-badge" id="dashboard-severity-risk-level" data-i18n="dashboard.riskSafe">安全</span>
                                                    </div>
                                                    <div class="dashboard-severity-insight-score-track" aria-hidden="true">
                                                        <div class="dashboard-severity-insight-score-fill" id="dashboard-severity-risk-fill" style="width: 0%"></div>
                                                    </div>
                                                    <div class="dashboard-severity-insight-score-meta">
                                                        <span class="dashboard-severity-insight-score-label" data-i18n="dashboard.riskScore">加权风险分</span>
                                                        <span class="dashboard-severity-insight-score-value" id="dashboard-severity-risk-score">0</span>
                                                    </div>
                                                </div>
                                                <div class="dashboard-severity-insight-urgent-group">
                                                    <span class="dashboard-severity-insight-label" data-i18n="dashboard.statusOpen">待处理</span>
                                                    <div class="dashboard-severity-insight-urgent">
                                                        <div class="dashboard-severity-insight-urgent-item u-critical" role="button" tabindex="0" onclick="switchPage('vulnerabilities')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('vulnerabilities'); }" title="查看待处理严重漏洞">
                                                            <span class="dashboard-severity-insight-urgent-value" id="dashboard-severity-urgent-critical">0</span>
                                                            <span class="dashboard-severity-insight-urgent-label" data-i18n="dashboard.severityCritical">严重</span>
                                                        </div>
                                                        <div class="dashboard-severity-insight-urgent-item u-high" role="button" tabindex="0" onclick="switchPage('vulnerabilities')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('vulnerabilities'); }" title="查看待处理高危漏洞">
                                                            <span class="dashboard-severity-insight-urgent-value" id="dashboard-severity-urgent-high">0</span>
                                                            <span class="dashboard-severity-insight-urgent-label" data-i18n="dashboard.severityHigh">高危</span>
                                                        </div>
                                                    </div>
                                                </div>
                                                <div class="dashboard-severity-insight-latest">
                                                    <span class="dashboard-severity-insight-label" data-i18n="dashboard.latestFound">最近发现</span>
                                                    <span class="dashboard-severity-insight-time" id="dashboard-severity-latest-time" data-i18n="dashboard.noneYet">暂无</span>
                                                </div>
                                            </aside>
                                            <div class="dashboard-severity-chart">
                                                <svg class="dashboard-severity-donut" id="dashboard-severity-donut" viewBox="0 0 480 260" preserveAspectRatio="xMidYMid meet" role="img" aria-labelledby="dashboard-severity-donut-title">
                                                    <title id="dashboard-severity-donut-title" data-i18n="dashboard.severityDistribution">漏洞严重程度分布</title>
                                                    <defs id="dashboard-severity-donut-defs"></defs>
                                                    <g id="dashboard-severity-donut-track"></g>
                                                    <g id="dashboard-severity-donut-leaders"></g>
                                                    <g id="dashboard-severity-donut-segments"></g>
                                                    <g id="dashboard-severity-donut-hits"></g>
                                                    <g id="dashboard-severity-donut-labels"></g>
                                                </svg>
                                                <div class="dashboard-severity-center" id="dashboard-severity-center">
                                                    <div class="dashboard-severity-center-value" id="dashboard-severity-total">0</div>
                                                    <div class="dashboard-severity-center-label" id="dashboard-severity-center-label" data-i18n="dashboard.totalVulns">总漏洞数</div>
                                                </div>
                                            </div>
                                            <div class="dashboard-severity-legend" id="dashboard-vuln-bars">
                                                <div class="dashboard-severity-legend-item" data-severity="critical" role="button" tabindex="0">
                                                    <span class="dashboard-severity-legend-dot critical"></span>
                                                    <span class="dashboard-severity-legend-label" data-i18n="dashboard.severityCritical">严重</span>
                                                    <span class="dashboard-severity-legend-value" id="dashboard-severity-critical">0</span>
                                                    <span class="dashboard-severity-legend-pct" id="dashboard-severity-critical-pct">0%</span>
                                                </div>
                                                <div class="dashboard-severity-legend-item" data-severity="high" role="button" tabindex="0">
                                                    <span class="dashboard-severity-legend-dot high"></span>
                                                    <span class="dashboard-severity-legend-label" data-i18n="dashboard.severityHigh">高危</span>
                                                    <span class="dashboard-severity-legend-value" id="dashboard-severity-high">0</span>
                                                    <span class="dashboard-severity-legend-pct" id="dashboard-severity-high-pct">0%</span>
                                                </div>
                                                <div class="dashboard-severity-legend-item" data-severity="medium" role="button" tabindex="0">
                                                    <span class="dashboard-severity-legend-dot medium"></span>
                                                    <span class="dashboard-severity-legend-label" data-i18n="dashboard.severityMedium">中危</span>
                                                    <span class="dashboard-severity-legend-value" id="dashboard-severity-medium">0</span>
                                                    <span class="dashboard-severity-legend-pct" id="dashboard-severity-medium-pct">0%</span>
                                                </div>
                                                <div class="dashboard-severity-legend-item" data-severity="low" role="button" tabindex="0">
                                                    <span class="dashboard-severity-legend-dot low"></span>
                                                    <span class="dashboard-severity-legend-label" data-i18n="dashboard.severityLow">低危</span>
                                                    <span class="dashboard-severity-legend-value" id="dashboard-severity-low">0</span>
                                                    <span class="dashboard-severity-legend-pct" id="dashboard-severity-low-pct">0%</span>
                                                </div>
                                                <div class="dashboard-severity-legend-item" data-severity="info" role="button" tabindex="0">
                                                    <span class="dashboard-severity-legend-dot info"></span>
                                                    <span class="dashboard-severity-legend-label" data-i18n="dashboard.severityInfo">信息</span>
                                                    <span class="dashboard-severity-legend-value" id="dashboard-severity-info">0</span>
                                                    <span class="dashboard-severity-legend-pct" id="dashboard-severity-info-pct">0%</span>
                                                </div>
                                            </div>
                                        </div>
                                        <!-- 处置状态 + 修复进度（利用 by_status 数据，避免下半部分留白） -->
                                        <div class="dashboard-severity-status">
                                            <div class="dashboard-severity-status-grid">
                                                <div class="dashboard-severity-status-cell s-open" role="button" tabindex="0" onclick="switchPage('vulnerabilities')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('vulnerabilities'); }">
                                                    <span class="dashboard-severity-status-icon" aria-hidden="true">
                                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
                                                    </span>
                                                    <div class="dashboard-severity-status-text">
                                                        <span class="dashboard-severity-status-value" id="dashboard-status-open">0</span>
                                                        <span class="dashboard-severity-status-label" data-i18n="dashboard.statusOpen">待处理</span>
                                                    </div>
                                                </div>
                                                <div class="dashboard-severity-status-cell s-confirmed" role="button" tabindex="0" onclick="switchPage('vulnerabilities')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('vulnerabilities'); }">
                                                    <span class="dashboard-severity-status-icon" aria-hidden="true">
                                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
                                                    </span>
                                                    <div class="dashboard-severity-status-text">
                                                        <span class="dashboard-severity-status-value" id="dashboard-status-confirmed">0</span>
                                                        <span class="dashboard-severity-status-label" data-i18n="dashboard.statusConfirmed">已确认</span>
                                                    </div>
                                                </div>
                                                <div class="dashboard-severity-status-cell s-fixed" role="button" tabindex="0" onclick="switchPage('vulnerabilities')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('vulnerabilities'); }">
                                                    <span class="dashboard-severity-status-icon" aria-hidden="true">
                                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><polyline points="9 12 11 14 15 10"/></svg>
                                                    </span>
                                                    <div class="dashboard-severity-status-text">
                                                        <span class="dashboard-severity-status-value" id="dashboard-status-fixed">0</span>
                                                        <span class="dashboard-severity-status-label" data-i18n="dashboard.statusFixed">已修复</span>
                                                    </div>
                                                </div>
                                                <div class="dashboard-severity-status-cell s-fp" role="button" tabindex="0" onclick="switchPage('vulnerabilities')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('vulnerabilities'); }">
                                                    <span class="dashboard-severity-status-icon" aria-hidden="true">
                                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg>
                                                    </span>
                                                    <div class="dashboard-severity-status-text">
                                                        <span class="dashboard-severity-status-value" id="dashboard-status-fp">0</span>
                                                        <span class="dashboard-severity-status-label" data-i18n="dashboard.statusFalsePositive">误报</span>
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="dashboard-severity-progress">
                                                <div class="dashboard-severity-progress-meta">
                                                    <span class="dashboard-severity-progress-title" data-i18n="dashboard.fixRate">修复率</span>
                                                    <span class="dashboard-severity-progress-value">
                                                        <span id="dashboard-fix-rate">0%</span>
                                                        <span class="dashboard-severity-progress-detail" id="dashboard-fix-detail">(0 / 0)</span>
                                                    </span>
                                                </div>
                                                <div class="dashboard-severity-progress-track" aria-hidden="true">
                                                    <div class="dashboard-severity-progress-fixed" id="dashboard-fix-progress-fixed" style="width: 0%"></div>
                                                    <div class="dashboard-severity-progress-confirmed" id="dashboard-fix-progress-confirmed" style="width: 0%"></div>
                                                </div>
                                                <div class="dashboard-severity-progress-legend">
                                                    <span class="dashboard-severity-progress-legend-item"><span class="dashboard-severity-progress-legend-dot legend-fixed"></span><span data-i18n="dashboard.statusFixed">已修复</span></span>
                                                    <span class="dashboard-severity-progress-legend-item"><span class="dashboard-severity-progress-legend-dot legend-confirmed"></span><span data-i18n="dashboard.statusConfirmed">已确认</span></span>
                                                    <span class="dashboard-severity-progress-legend-item"><span class="dashboard-severity-progress-legend-dot legend-open"></span><span data-i18n="dashboard.statusOpen">待处理</span></span>
                                                </div>
                                            </div>
                                        </div>
                                    </section>
                                    <section class="dashboard-section dashboard-section-recent-vulns">
                                        <div class="dashboard-section-header">
                                            <h3 class="dashboard-section-title" data-i18n="dashboard.recentVulns">最近漏洞</h3>
                                            <a class="dashboard-section-link" onclick="switchPage('vulnerabilities')" data-i18n="dashboard.viewAll">查看全部 →</a>
                                        </div>
                                        <div class="dashboard-recent-vulns" id="dashboard-recent-vulns">
                                            <div class="dashboard-recent-vulns-empty" id="dashboard-recent-vulns-empty" data-i18n="dashboard.noVulnYet">暂无最近漏洞</div>
                                        </div>
                                    </section>
                                    <!-- C2 概览：介于「最近漏洞」与「批量任务队列」之间 -->
                                    <section class="dashboard-section dashboard-section-c2" id="dashboard-section-c2" hidden>
                                        <div class="dashboard-section-header">
                                            <h3 class="dashboard-section-title" data-i18n="dashboard.c2OverviewTitle">C2 概览</h3>
                                            <a class="dashboard-section-link" onclick="switchPage('c2')" data-i18n="dashboard.c2GoManage">进入 C2 →</a>
                                        </div>
                                        <div class="dashboard-c2-strip">
                                            <div class="dashboard-c2-stat" role="button" tabindex="0" onclick="switchPage('c2-listeners')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('c2-listeners'); }" data-i18n="dashboard.c2ClickListeners" data-i18n-attr="title" title="查看监听器">
                                                <span class="dashboard-c2-stat-value" id="dashboard-c2-listeners-running">-</span>
                                                <span class="dashboard-c2-stat-label" data-i18n="dashboard.c2ListenersRunning">运行中监听器</span>
                                            </div>
                                            <div class="dashboard-c2-stat" role="button" tabindex="0" onclick="switchPage('c2-sessions')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('c2-sessions'); }" data-i18n="dashboard.c2ClickSessions" data-i18n-attr="title" title="查看会话">
                                                <span class="dashboard-c2-stat-value" id="dashboard-c2-sessions-online">-</span>
                                                <span class="dashboard-c2-stat-label" data-i18n="dashboard.c2SessionsOnline">在线会话</span>
                                            </div>
                                            <div class="dashboard-c2-stat" role="button" tabindex="0" onclick="switchPage('c2-tasks')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('c2-tasks'); }" data-i18n="dashboard.c2ClickTasks" data-i18n-attr="title" title="查看任务">
                                                <span class="dashboard-c2-stat-value" id="dashboard-c2-tasks-pending">-</span>
                                                <span class="dashboard-c2-stat-label" data-i18n="dashboard.c2TasksPending">待审 / 排队任务</span>
                                            </div>
                                        </div>
                                    </section>
                                    <section class="dashboard-section dashboard-section-overview">
                                        <div class="dashboard-section-header">
                                            <h3 class="dashboard-section-title" data-i18n="dashboard.batchQueues">批量任务队列</h3>
                                            <a class="dashboard-section-link" onclick="switchPage('tasks')" data-i18n="dashboard.viewAll">查看全部 →</a>
                                        </div>
                                        <div class="dashboard-overview-list">
                                            <div class="dashboard-overview-item dashboard-overview-item-batch" role="button" tabindex="0" onclick="switchPage('tasks')" onkeydown="if(event.key==='Enter'||event.key===' ') { event.preventDefault(); switchPage('tasks'); }">
                                                <span class="dashboard-overview-icon dashboard-overview-icon-batch" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg></span>
                                                <div class="dashboard-overview-content">
                                                    <div class="dashboard-overview-header">
                                                        <span class="dashboard-overview-label" data-i18n="dashboard.batchQueues">批量任务队列</span>
                                                        <span class="dashboard-overview-total" id="dashboard-batch-total">-</span>
                                                    </div>
                                                    <div class="dashboard-overview-stats">
                                                        <span class="dashboard-overview-stat dashboard-overview-stat-pending">
                                                            <span class="dashboard-overview-stat-badge badge-pending"></span>
                                                            <span class="dashboard-overview-stat-value" id="dashboard-batch-pending">-</span>
                                                            <span class="dashboard-overview-stat-label" data-i18n="dashboard.pending">待执行</span>
                                                        </span>
                                                        <span class="dashboard-overview-stat dashboard-overview-stat-running">
                                                            <span class="dashboard-overview-stat-badge badge-running"></span>
                                                            <span class="dashboard-overview-stat-value" id="dashboard-batch-running">-</span>
                                                            <span class="dashboard-overview-stat-label" data-i18n="dashboard.executing">执行中</span>
                                                        </span>
                                                        <span class="dashboard-overview-stat dashboard-overview-stat-done">
                                                            <span class="dashboard-overview-stat-badge badge-done"></span>
                                                            <span class="dashboard-overview-stat-value" id="dashboard-batch-done">-</span>
                                                            <span class="dashboard-overview-stat-label" data-i18n="dashboard.completed">已完成</span>
                                                        </span>
                                                    </div>
                                                    <div class="dashboard-overview-progress">
                                                        <div class="dashboard-overview-progress-bar">
                                                            <div class="dashboard-overview-progress-segment dashboard-overview-progress-pending" id="dashboard-batch-progress-pending" style="width: 0%"></div>
                                                            <div class="dashboard-overview-progress-segment dashboard-overview-progress-running" id="dashboard-batch-progress-running" style="width: 0%"></div>
                                                            <div class="dashboard-overview-progress-segment dashboard-overview-progress-done" id="dashboard-batch-progress-done" style="width: 0%"></div>
                                                        </div>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </section>
                                    <!-- 推荐操作：基于当前数据状态智能生成（如「修复 4 个待处理严重漏洞」「审批 2 个 HITL」），
                                         比纯静态导航更有意义；当没有任何推荐时整个 section 隐藏 -->
                                    <section class="dashboard-section dashboard-section-recommend" id="dashboard-section-recommend" hidden>
                                        <div class="dashboard-section-header">
                                            <h3 class="dashboard-section-title" data-i18n="dashboard.recommendedActions">推荐操作</h3>
                                            <span class="dashboard-section-hint" data-i18n="dashboard.recommendedActionsHint">基于当前状态自动生成</span>
                                        </div>
                                        <div class="dashboard-recommend-list" id="dashboard-recommend-list"></div>
                                    </section>
                                </div>
                                <div class="dashboard-side">
                                    <section class="dashboard-section dashboard-section-tools">
                                        <div class="dashboard-section-header">
                                            <h3 class="dashboard-section-title" data-i18n="dashboard.toolsExecCount">工具执行次数</h3>
                                            <a class="dashboard-section-link" onclick="switchPage('mcp-monitor')" data-i18n="dashboard.viewAll">查看全部 →</a>
                                        </div>
                                        <div class="dashboard-tools-chart-wrap">
                                            <div class="dashboard-tools-chart-placeholder" id="dashboard-tools-pie-placeholder" data-i18n="common.noData">暂无数据</div>
                                            <div class="dashboard-tools-bar-chart" id="dashboard-tools-bar-chart"></div>
                                        </div>
                                    </section>
                                    <!-- 最近事件：拉 /api/notifications/summary 取最新 3 条；空时整个隐藏 -->
                                    <section class="dashboard-section dashboard-section-events" id="dashboard-section-events" hidden>
                                        <div class="dashboard-section-header">
                                            <h3 class="dashboard-section-title" data-i18n="dashboard.recentEvents">最近事件</h3>
                                            <a class="dashboard-section-link" onclick="if(typeof toggleNotificationDropdown==='function') toggleNotificationDropdown()" data-i18n="dashboard.viewAll">查看全部 →</a>
                                        </div>
                                        <div class="dashboard-events-list" id="dashboard-events-list"></div>
                                    </section>
                                    <section class="dashboard-section dashboard-section-resources">
                                        <h3 class="dashboard-section-title" data-i18n="dashboard.capabilities">能力总览</h3>
                                        <div class="dashboard-resource-list" id="dashboard-resource-list">
                                            <a class="dashboard-resource-item" onclick="switchPage('mcp-management')" role="button" tabindex="0">
                                                <span class="dashboard-resource-icon dashboard-resource-icon-mcp" aria-hidden="true">
                                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>
                                                </span>
                                                <span class="dashboard-resource-label" data-i18n="dashboard.mcpTools">MCP 工具</span>
                                                <span class="dashboard-resource-value" id="dashboard-resource-tools">-</span>
                                            </a>
                                            <!-- External MCP 服务器健康度：N 运行 / N 异常；只有配置过 External MCP 才显示 -->
                                            <a class="dashboard-resource-item" id="dashboard-resource-external-mcp-row" onclick="switchPage('mcp-management')" role="button" tabindex="0" hidden>
                                                <span class="dashboard-resource-icon dashboard-resource-icon-external" aria-hidden="true">
                                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
                                                </span>
                                                <span class="dashboard-resource-label" data-i18n="dashboard.externalMcpServers">External MCP</span>
                                                <span class="dashboard-resource-value" id="dashboard-resource-external-mcp">
                                                    <span id="dashboard-resource-external-mcp-text">-</span>
                                                    <span class="dashboard-resource-health" id="dashboard-resource-external-mcp-health" hidden></span>
                                                </span>
                                            </a>
                                            <a class="dashboard-resource-item" onclick="switchPage('skills-management')" role="button" tabindex="0">
                                                <span class="dashboard-resource-icon dashboard-resource-icon-skills" aria-hidden="true">
                                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
                                                </span>
                                                <span class="dashboard-resource-label" data-i18n="dashboard.skillsLabel">Skills</span>
                                                <span class="dashboard-resource-value" id="dashboard-resource-skills">-</span>
                                            </a>
                                            <a class="dashboard-resource-item" onclick="switchPage('knowledge-management')" role="button" tabindex="0">
                                                <span class="dashboard-resource-icon dashboard-resource-icon-knowledge" aria-hidden="true">
                                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
                                                </span>
                                                <span class="dashboard-resource-label" data-i18n="dashboard.knowledgeLabel">知识</span>
                                                <span class="dashboard-resource-value" id="dashboard-resource-knowledge">-</span>
                                            </a>
                                            <a class="dashboard-resource-item" onclick="switchPage('roles-management')" role="button" tabindex="0">
                                                <span class="dashboard-resource-icon dashboard-resource-icon-roles" aria-hidden="true">
                                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
                                                </span>
                                                <span class="dashboard-resource-label" data-i18n="dashboard.rolesLabel">角色</span>
                                                <span class="dashboard-resource-value" id="dashboard-resource-roles">-</span>
                                            </a>
                                            <a class="dashboard-resource-item" onclick="switchPage('agents-management')" role="button" tabindex="0">
                                                <span class="dashboard-resource-icon dashboard-resource-icon-agents" aria-hidden="true">
                                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg>
                                                </span>
                                                <span class="dashboard-resource-label" data-i18n="dashboard.agentsLabel">Agents</span>
                                                <span class="dashboard-resource-value" id="dashboard-resource-agents">-</span>
                                            </a>
                                            <!-- WebShell 连接：渗透落地后建立的 foothold，对安全运维场景非常关键 -->
                                            <a class="dashboard-resource-item" onclick="switchPage('webshell')" role="button" tabindex="0">
                                                <span class="dashboard-resource-icon dashboard-resource-icon-webshell" aria-hidden="true">
                                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>
                                                </span>
                                                <span class="dashboard-resource-label" data-i18n="dashboard.webshellLabel">WebShell</span>
                                                <span class="dashboard-resource-value" id="dashboard-resource-webshell">-</span>
                                            </a>
                                        </div>
                                    </section>
                                </div>
                            </div>
                            <!-- "开始你的安全之旅" CTA：默认显示；当用户已经有数据（任务/漏洞/调用）后，由 JS 隐藏避免冗余 -->
                            <div class="dashboard-cta-block" id="dashboard-cta-block">
                                <div class="dashboard-cta-content">
                                    <div class="dashboard-cta-icon" aria-hidden="true">
                                        <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
                                    </div>
                                    <div class="dashboard-cta-copy">
                                        <p class="dashboard-cta-text" data-i18n="dashboard.ctaTitle">开始你的安全之旅</p>
                                        <p class="dashboard-cta-sub" data-i18n="dashboard.ctaSub">在对话中描述目标，AI 将协助执行扫描与漏洞分析</p>
                                    </div>
                                </div>
                                <button class="dashboard-cta-btn" onclick="switchPage('chat')">
                                    <span data-i18n="dashboard.goToChat">前往对话</span>
                                    <span class="dashboard-cta-btn-arrow" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M5 12h14M12 5l7 7-7 7"/></svg></span>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 对话页面 -->
                <div id="page-chat" class="page">
                    <div class="chat-page-layout">
                        <!-- 历史对话侧边栏（可折叠，与主导航侧边栏类似） -->
                        <aside class="conversation-sidebar" id="conversation-sidebar">
                            <!-- 头部一行：折叠与「新对话」并排，避免绝对定位重叠（flex 为最佳实践） -->
                            <div class="sidebar-header conversation-sidebar-header">
                                <button type="button" class="new-chat-btn" onclick="startNewConversation()">
                                    <span>+</span> <span data-i18n="chat.newChat">新对话</span>
                                </button>
                                <button type="button" class="conversation-sidebar-collapse-btn" onclick="toggleConversationSidebar()" data-i18n="chat.toggleConversationPanel" data-i18n-attr="title" data-i18n-skip-text="true" title="折叠/展开对话列表" aria-label="折叠/展开对话列表">
                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                                        <path d="M15 18l-6-6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    </svg>
                                </button>
                            </div>
                            <div class="sidebar-content">
                                <!-- 全局搜索 -->
                                <div class="conversation-search-box" style="margin-bottom: 16px; margin-top: 16px;">
                                    <input type="text" id="conversation-search-input" data-i18n="chat.searchHistory" data-i18n-attr="placeholder" placeholder="搜索历史记录..." 
                                           oninput="handleConversationSearch(this.value)" 
                                           onkeypress="if(event.key === 'Enter') handleConversationSearch(this.value)" />
                                    <button class="conversation-search-clear" id="conversation-search-clear" 
                                            onclick="clearConversationSearch()" style="display: none;" data-i18n="common.clearSearch" data-i18n-attr="title" title="清除搜索">
                                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                            <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
                                            <path d="M15 9l-6 6M9 9l6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                        </svg>
                                    </button>
                                </div>
                                
                                <!-- 对话分组 -->
                                <div class="conversation-groups-section">
                                    <div class="section-header">
                                        <span class="section-title" data-i18n="chat.conversationGroups">对话分组</span>
                                        <button class="add-group-btn" onclick="showCreateGroupModal()" data-i18n="chat.addGroup" data-i18n-attr="title" data-i18n-skip-text="true" title="新建分组">
                                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                <path d="M12 5v14M5 12h14" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                            </svg>
                                        </button>
                                    </div>
                                    <div id="conversation-groups-list" class="conversation-groups-list"></div>
                                </div>
                                
                                <!-- 最近对话 -->
                                <div class="recent-conversations-section">
                                    <div class="section-header">
                                        <span class="section-title" data-i18n="chat.recentConversations">最近对话</span>
                                        <button class="batch-manage-btn" onclick="showBatchManageModal()" data-i18n="chat.batchManage" data-i18n-attr="title" data-i18n-skip-text="true" title="批量管理">
                                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                <line x1="3" y1="12" x2="21" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                                <line x1="3" y1="6" x2="21" y2="6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                                <line x1="3" y1="18" x2="21" y2="18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                                <circle cx="8" cy="6" r="1" fill="currentColor"/>
                                                <circle cx="8" cy="12" r="1" fill="currentColor"/>
                                                <circle cx="8" cy="18" r="1" fill="currentColor"/>
                                            </svg>
                                        </button>
                                    </div>
                                    <div id="conversations-list" class="conversations-list"></div>
                                </div>
                            </div>
                            <div id="chat-reasoning-wrapper" class="chat-reasoning-wrapper conversation-reasoning-card conversation-reasoning-collapsed" style="display: none;">
                                <button type="button" id="conversation-reasoning-toggle" class="conversation-reasoning-card-header" onclick="toggleConversationReasoningCard()" aria-expanded="false" aria-controls="conversation-reasoning-body" data-i18n="chat.reasoningCompactAria" data-i18n-attr="aria-label,title" data-i18n-skip-text="true" aria-label="模型推理选项" title="模型推理选项">
                                    <div class="conversation-reasoning-heading">
                                        <span class="conversation-reasoning-icon" aria-hidden="true">
                                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                <circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="1.75"/>
                                                <path d="M16 16l5 5" stroke="currentColor" stroke-width="1.75" stroke-linecap="round"/>
                                            </svg>
                                        </span>
                                        <div class="conversation-reasoning-heading-text">
                                            <span class="conversation-reasoning-title" data-i18n="chat.reasoningPanelTitle">模型推理</span>
                                            <span id="chat-reasoning-summary" class="conversation-reasoning-summary"></span>
                                        </div>
                                    </div>
                                </button>
                                <div id="conversation-reasoning-body" class="conversation-reasoning-body" role="region">
                                    <p class="chat-reasoning-panel-hint" data-i18n="chat.reasoningPanelHint">仅 Eino 请求生效，与系统设置中的默认值合并。</p>
                                    <div class="chat-reasoning-fields">
                                        <div class="chat-reasoning-field">
                                            <label class="chat-reasoning-field-label" for="chat-reasoning-mode"><span data-i18n="chat.reasoningModeLabel">模式</span></label>
                                            <select id="chat-reasoning-mode" class="chat-reasoning-select" onchange="persistChatReasoningPrefs()">
                                                <option value="default" data-i18n="chat.reasoningModeDefault">跟随系统</option>
                                                <option value="off" data-i18n="chat.reasoningModeOff">关闭</option>
                                                <option value="on" data-i18n="chat.reasoningModeOn">开启</option>
                                                <option value="auto" data-i18n="chat.reasoningModeAuto">自动</option>
                                            </select>
                                        </div>
                                        <div class="chat-reasoning-field">
                                            <label class="chat-reasoning-field-label" for="chat-reasoning-effort"><span data-i18n="chat.reasoningEffortLabel">推理强度</span></label>
                                            <select id="chat-reasoning-effort" class="chat-reasoning-select" onchange="persistChatReasoningPrefs()">
                                                <option value="" data-i18n="chat.reasoningEffortUnset">不指定</option>
                                                <option value="low">low</option>
                                                <option value="medium">medium</option>
                                                <option value="high">high</option>
                                                <option value="xhigh">xhigh</option>
                                                <option value="max">max</option>
                                            </select>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="hitl-sidebar-card hitl-sidebar-collapsed" id="hitl-sidebar-card">
                                <div class="hitl-sidebar-card-header" onclick="toggleHitlSidebarCard()">
                                    <div class="hitl-sidebar-heading">
                                        <span class="hitl-sidebar-icon" aria-hidden="true">
                                            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                <path d="M12 2L4 5v6.09c0 5.05 3.41 9.76 8 10.91 4.59-1.15 8-5.86 8-10.91V5l-8-3z" stroke="currentColor" stroke-width="1.75" stroke-linejoin="round"/>
                                                <path d="M9.5 12.5l2 2 3-4" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
                                            </svg>
                                        </span>
                                        <div class="hitl-sidebar-heading-text">
                                            <span class="hitl-sidebar-title" data-i18n="chat.hitlTitle">人机协同</span>
                                            <span class="hitl-sidebar-subtitle" data-i18n="chat.hitlCardSubtitle">审批与白名单</span>
                                        </div>
                                    </div>
                                    <div class="hitl-sidebar-header-actions">
                                        <button type="button" class="hitl-apply-btn" id="hitl-apply-btn" onclick="event.stopPropagation(); window.applyHitlSidebarConfig && window.applyHitlSidebarConfig()">
                                            <span data-i18n="chat.hitlApply">应用</span>
                                        </button>
                                    </div>
                                </div>
                                <div class="hitl-sidebar-body" id="hitl-sidebar-body">
                                    <div id="hitl-apply-feedback" class="hitl-apply-feedback" role="status" aria-live="polite"></div>
                                    <div class="hitl-sidebar-config">
                                        <div class="hitl-config-field">
                                            <label class="hitl-config-label" for="hitl-mode-select" data-i18n="chat.hitlModeLabel">模式</label>
                                            <select id="hitl-mode-select" class="hitl-config-select">
                                                <option value="off" data-i18n="chat.hitlModeOff">关闭</option>
                                                <option value="approval" data-i18n="chat.hitlModeApproval">审批模式</option>
                                                <option value="review_edit" data-i18n="chat.hitlModeReviewEdit">审查编辑</option>
                                            </select>
                                        </div>
                                        <div class="hitl-config-field hitl-config-field--tools">
                                            <label class="hitl-config-label" for="hitl-sensitive-tools" data-i18n="chat.hitlWhitelistTools">白名单工具（免审批，逗号分隔）</label>
                                            <textarea id="hitl-sensitive-tools" class="hitl-config-textarea" rows="3" spellcheck="false" autocomplete="off" data-i18n="chat.hitlWhitelistPlaceholder" data-i18n-attr="placeholder" placeholder=""></textarea>
                                            <p class="hitl-config-hint" data-i18n="chat.hitlWhitelistHint">每行一个或逗号分隔；与 config 中全局白名单合并展示。</p>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </aside>
                        
                        <!-- 分组详情页面 -->
                        <div id="group-detail-page" class="group-detail-page" style="display: none;">
                            <div class="group-detail-header">
                                <button class="back-btn" onclick="exitGroupDetail()">
                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path d="M19 12H5M12 19l-7-7 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    </svg>
                                </button>
                                <h2 id="group-detail-title" class="group-detail-title"></h2>
                                <div class="group-detail-actions">
                                    <button class="group-action-btn" onclick="toggleGroupSearch()" data-i18n="chatGroup.search" data-i18n-attr="title" title="搜索" id="group-search-toggle-btn">
                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                            <circle cx="11" cy="11" r="8" stroke="currentColor" stroke-width="2"/>
                                            <path d="m21 21-4.35-4.35" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                        </svg>
                                    </button>
                                    <button class="group-action-btn" onclick="editGroup()" data-i18n="chatGroup.edit" data-i18n-attr="title" title="编辑">
                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                            <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                            <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                        </svg>
                                    </button>
                                    <button class="group-action-btn delete-btn" onclick="deleteGroup()" data-i18n="chatGroup.delete" data-i18n-attr="title" title="删除">
                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                            <path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2m3 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6h14z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                        </svg>
                                    </button>
                                </div>
                            </div>
                            <div id="group-search-container" class="group-search-container" style="display: none;">
                                <div class="group-search-input-wrapper">
                                    <input type="text" id="group-search-input" class="group-search-input" data-i18n="chat.searchInGroup" data-i18n-attr="placeholder" placeholder="搜索分组中的对话..." onkeyup="handleGroupSearchInput(event)" oninput="handleGroupSearchInput(event)">
                                    <button class="group-search-clear-btn" onclick="clearGroupSearch()" data-i18n="common.clearSearch" data-i18n-attr="title" title="清除搜索" id="group-search-clear-btn" style="display: none;">
                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                            <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
                                            <path d="m8 8 8 8M16 8l-8 8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                        </svg>
                                    </button>
                                </div>
                            </div>
                            <div class="group-detail-content">
                                <div id="group-conversations-list" class="group-conversations-list"></div>
                            </div>
                        </div>

                        <!-- 对话界面 -->
                        <div class="chat-container">
                            <!-- 会话顶部栏（只在有会话选中时显示） -->
                            <div id="conversation-header" class="conversation-header" style="display: none;">
                                <div class="conversation-header-content">
                                    <button id="attack-chain-btn" class="attack-chain-btn" data-i18n="chat.viewAttackChain" data-i18n-attr="title" data-i18n-skip-text="true" title="查看攻击链" disabled>
                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                            <path d="M10.5 13.5l3-3M8 8H5a4 4 0 1 0 0 8h3m8-8h3a4 4 0 0 1 0 8h-3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                        </svg>
                                        <span data-i18n="chat.attackChain">攻击链</span>
                                    </button>
                                </div>
                            </div>
                            <div id="active-tasks-bar" class="active-tasks-bar"></div>
                            <div id="chat-messages" class="chat-messages"></div>
                            <button type="button" id="chat-scroll-to-bottom" class="chat-scroll-to-bottom" aria-label="回到底部" title="回到底部">↓ 回到底部</button>
                            <div id="chat-input-container" class="chat-input-container">
                                <div class="chat-input-primary-row">
                                <div class="chat-input-leading">
                                <div class="role-selector-wrapper project-selector-wrapper">
                                    <button type="button" id="chat-project-btn" class="role-selector-btn" onclick="toggleChatProjectPanel()" aria-label="选择项目" aria-haspopup="listbox" aria-expanded="false" title="绑定项目后共享事实黑板（跨对话）" data-i18n="projects.chatSelectorButton" data-i18n-attr="aria-label,title">
                                        <span class="role-selector-icon" aria-hidden="true">📁</span>
                                        <span id="chat-project-text" class="role-selector-text" data-i18n="projects.noProject">无项目</span>
                                        <svg class="role-selector-arrow" width="10" height="10" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                                            <path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                        </svg>
                                    </button>
                                    <div id="chat-project-panel" class="role-selection-panel chat-project-panel" style="display: none;" role="listbox" aria-labelledby="chat-project-panel-title">
                                        <div class="role-selection-panel-header">
                                            <h3 id="chat-project-panel-title" class="role-selection-panel-title" data-i18n="projects.selectProject">选择项目</h3>
                                            <button type="button" class="role-selection-panel-close" onclick="closeChatProjectPanel()" title="关闭" aria-label="关闭">
                                                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                    <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                                </svg>
                                            </button>
                                        </div>
                                        <div class="chat-project-panel-body">
                                            <div id="chat-project-list" class="role-selection-list-main"></div>
                                            <div class="chat-project-panel-footer">
                                                <button type="button" class="role-selection-item-main chat-project-panel-create-btn" onclick="showNewProjectModalFromChat()">
                                                    <span class="chat-project-panel-create-icon" aria-hidden="true">+</span>
                                                    <span class="chat-project-panel-create-label" data-i18n="projects.newProject">新建项目</span>
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div id="role-selector-wrapper" class="role-selector-wrapper">
                                    <button type="button" id="role-selector-btn" class="role-selector-btn" onclick="toggleRoleSelectionPanel()" data-i18n="chat.selectRole" data-i18n-attr="title" title="选择角色">
                                        <span id="role-selector-icon" class="role-selector-icon">🔵</span>
                                        <span id="role-selector-text" class="role-selector-text" data-i18n="chat.defaultRole">默认</span>
                                        <svg class="role-selector-arrow" width="10" height="10" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                            <path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                        </svg>
                                    </button>
                                    <!-- 角色选择下拉面板 -->
                                    <div id="role-selection-panel" class="role-selection-panel" style="display: none;">
                                        <div class="role-selection-panel-header">
                                            <h3 class="role-selection-panel-title" data-i18n="chatGroup.rolePanelTitle">选择角色</h3>
                                            <button class="role-selection-panel-close" onclick="closeRoleSelectionPanel()" data-i18n="common.close" data-i18n-attr="title" title="关闭">
                                                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                    <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                                </svg>
                                            </button>
                                        </div>
                                        <div id="role-selection-list" class="role-selection-list-main"></div>
                                    </div>
                                </div>
                                <div id="agent-mode-wrapper" class="agent-mode-wrapper" style="display: none;">
                                    <div class="agent-mode-inner">
                                        <button type="button" id="agent-mode-btn" class="role-selector-btn agent-mode-btn" onclick="toggleAgentModePanel()" data-i18n="chat.agentModeSelectAria" data-i18n-attr="aria-label,title" data-i18n-skip-text="true" aria-label="选择对话执行模式" aria-haspopup="listbox" aria-expanded="false" title="选择对话执行模式">
                                            <span id="agent-mode-icon" class="role-selector-icon" aria-hidden="true">🤖</span>
                                            <span id="agent-mode-text" class="role-selector-text">单代理</span>
                                            <svg class="role-selector-arrow" width="10" height="10" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                                                <path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                            </svg>
                                        </button>
                                        <div id="agent-mode-panel" class="agent-mode-panel" style="display: none;" role="listbox" aria-labelledby="agent-mode-panel-title">
                                            <div class="role-selection-panel-header agent-mode-panel-header">
                                                <h3 id="agent-mode-panel-title" class="role-selection-panel-title" data-i18n="chat.agentModePanelTitle">对话模式</h3>
                                                <button type="button" class="role-selection-panel-close" onclick="closeAgentModePanel()" data-i18n="common.close" data-i18n-attr="title" title="关闭">
                                                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                        <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                                    </svg>
                                                </button>
                                            </div>
                                            <div class="agent-mode-options">
                                                <button type="button" class="role-selection-item-main agent-mode-option" data-value="react" role="option" onclick="selectAgentMode('react')">
                                                    <div class="role-selection-item-icon-main" aria-hidden="true">🤖</div>
                                                    <div class="role-selection-item-content-main">
                                                        <div class="role-selection-item-name-main" data-i18n="chat.agentModeReactNative">原生 ReAct 模式</div>
                                                        <div class="role-selection-item-description-main" data-i18n="chat.agentModeReactNativeHint">经典单代理 ReAct 与 MCP 工具（/api/agent-loop）</div>
                                                    </div>
                                                    <div class="role-selection-checkmark-main agent-mode-check" data-agent-mode-check="react">✓</div>
                                                </button>
                                                <button type="button" class="role-selection-item-main agent-mode-option" data-value="eino_single" role="option" onclick="selectAgentMode('eino_single')">
                                                    <div class="role-selection-item-icon-main" aria-hidden="true">⚡</div>
                                                    <div class="role-selection-item-content-main">
                                                        <div class="role-selection-item-name-main" data-i18n="chat.agentModeEinoSingle">Eino 单代理（ADK）</div>
                                                        <div class="role-selection-item-description-main" data-i18n="chat.agentModeEinoSingleHint">CloudWeGo Eino ChatModelAgent + Runner，MCP 工具（/api/eino-agent）</div>
                                                    </div>
                                                    <div class="role-selection-checkmark-main agent-mode-check" data-agent-mode-check="eino_single">✓</div>
                                                </button>
                                                <button type="button" class="role-selection-item-main agent-mode-option" data-value="deep" role="option" onclick="selectAgentMode('deep')">
                                                    <div class="role-selection-item-icon-main" aria-hidden="true">🧩</div>
                                                    <div class="role-selection-item-content-main">
                                                        <div class="role-selection-item-name-main" data-i18n="chat.agentModeDeep">Deep（DeepAgent）</div>
                                                        <div class="role-selection-item-description-main" data-i18n="chat.agentModeDeepHint">Eino DeepAgent，task 调度子代理</div>
                                                    </div>
                                                    <div class="role-selection-checkmark-main agent-mode-check" data-agent-mode-check="deep">✓</div>
                                                </button>
                                                <button type="button" class="role-selection-item-main agent-mode-option" data-value="plan_execute" role="option" onclick="selectAgentMode('plan_execute')">
                                                    <div class="role-selection-item-icon-main" aria-hidden="true">📋</div>
                                                    <div class="role-selection-item-content-main">
                                                        <div class="role-selection-item-name-main" data-i18n="chat.agentModePlanExecuteLabel">Plan-Execute</div>
                                                        <div class="role-selection-item-description-main" data-i18n="chat.agentModePlanExecuteHint">规划 → 执行 → 重规划（单执行器工具链）</div>
                                                    </div>
                                                    <div class="role-selection-checkmark-main agent-mode-check" data-agent-mode-check="plan_execute">✓</div>
                                                </button>
                                                <button type="button" class="role-selection-item-main agent-mode-option" data-value="supervisor" role="option" onclick="selectAgentMode('supervisor')">
                                                    <div class="role-selection-item-icon-main" aria-hidden="true">🎯</div>
                                                    <div class="role-selection-item-content-main">
                                                        <div class="role-selection-item-name-main" data-i18n="chat.agentModeSupervisorLabel">Supervisor</div>
                                                        <div class="role-selection-item-description-main" data-i18n="chat.agentModeSupervisorHint">监督者协调，transfer 委派子代理</div>
                                                    </div>
                                                    <div class="role-selection-checkmark-main agent-mode-check" data-agent-mode-check="supervisor">✓</div>
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                    <input type="hidden" id="agent-mode-select" value="react" autocomplete="off">
                                </div>
                                </div>
                                <div class="chat-input-with-files">
                                    <div id="chat-file-list" class="chat-file-list" aria-label="已选文件列表"></div>
                                    <div id="chat-attachment-progress" class="chat-upload-progress-row" hidden role="status" aria-live="polite">
                                        <div class="chat-upload-progress-track" aria-hidden="true"><div class="chat-upload-progress-fill" id="chat-attachment-progress-fill"></div></div>
                                        <span class="chat-upload-progress-label" id="chat-attachment-progress-label"></span>
                                    </div>
                                    <div class="chat-input-field">
                                        <textarea id="chat-input" data-i18n="chat.inputPlaceholder" data-i18n-attr="placeholder" data-i18n-skip-text="true" placeholder="输入测试目标或命令... (输入 @ 选择工具 | Shift+Enter 换行，Enter 发送)" rows="1"></textarea>
                                        <div id="mention-suggestions" class="mention-suggestions" role="listbox" aria-label="工具提及候选"></div>
                                    </div>
                                </div>
                                <input type="file" id="chat-file-input" class="chat-file-input-hidden" multiple accept="*" data-i18n="chat.selectFile" data-i18n-attr="title" title="选择文件">
                                <button type="button" class="chat-upload-btn" onclick="document.getElementById('chat-file-input').click()" data-i18n="chat.uploadFile" data-i18n-attr="title" title="上传文件（可多选或拖拽到此处）">
                                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    </svg>
                                </button>
                                <button type="button" class="send-btn" id="chat-send-btn" onclick="sendMessage()">
                                    <span data-i18n="chat.send">发送</span>
                                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <path d="M5 12h14M12 5l7 7-7 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                    </svg>
                                </button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div id="page-hitl" class="page">
                    <div class="page-header">
                        <h2 data-i18n="hitl.pageTitle">人机协同审批</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="refreshHitlPending()" data-i18n="common.refresh">刷新</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <div class="settings-section">
                            <h3 data-i18n="hitl.pendingTitle">待处理审批</h3>
                            <div id="hitl-pending-list" class="hitl-pending-list"></div>
                        </div>
                    </div>
                </div>

                <!-- MCP状态监控页面 -->
                <div id="page-mcp-monitor" class="page">
                    <div class="page-header">
<h2 data-i18n="mcp.monitorTitle">MCP 状态监控</h2>
                    <button class="btn-secondary" onclick="refreshMonitorPanel()"><span data-i18n="common.refresh">刷新</span></button>
                    </div>
                    <div class="page-content">
                        <div class="monitor-sections">
                            <section class="monitor-section monitor-overview">
                                <div class="section-header monitor-stats-section-header">
                                    <div class="monitor-stats-header-text">
                                        <h3 data-i18n="mcp.execStats">执行统计</h3>
                                        <p id="monitor-stats-subtitle" class="monitor-stats-subtitle" hidden></p>
                                    </div>
                                </div>
                                <div id="monitor-stats" class="mcp-exec-stats-root">
                                    <div class="monitor-empty" data-i18n="mcpMonitor.loading">加载中...</div>
                                </div>
                            </section>
                            <section class="monitor-section monitor-executions">
                                <div class="section-header">
                                    <h3 data-i18n="mcp.latestExecutions">最新执行记录</h3>
                                    <div class="section-actions">
                                        <label>
                                            <span data-i18n="mcp.toolSearch">工具搜索</span>
                                            <input type="text" id="monitor-tool-filter" data-i18n="mcp.toolSearchPlaceholder" data-i18n-attr="placeholder" placeholder="输入工具名称..." oninput="handleToolFilterInput()" onkeydown="if(event.key==='Enter') applyMonitorFilters()" />
                                        </label>
                                        <label>
                                            <span data-i18n="mcp.statusFilter">状态筛选</span>
                                            <select id="monitor-status-filter" onchange="applyMonitorFilters()">
                                                <option value="all" data-i18n="mcp.filterAll">全部</option>
                                                <option value="completed" data-i18n="mcpMonitor.statusCompleted">已完成</option>
                                                <option value="running" data-i18n="mcpMonitor.statusRunning">执行中</option>
                                                <option value="failed" data-i18n="mcpMonitor.statusFailed">失败</option>
                                                <option value="cancelled" data-i18n="mcpMonitor.statusCancelled">已终止</option>
                                            </select>
                                        </label>
                                    </div>
                                </div>
                                <div id="monitor-batch-actions" class="monitor-batch-actions" style="display: none;">
                                    <div class="batch-actions-info">
                                        <span id="monitor-selected-count">已选择 0 项</span>
                                    </div>
                                    <div class="batch-actions-buttons">
                                        <button class="btn-secondary" onclick="selectAllExecutions()" data-i18n="mcp.selectAll">全选</button>
                                        <button class="btn-secondary" onclick="deselectAllExecutions()" data-i18n="mcpMonitor.deselectAll">取消全选</button>
                                        <button class="btn-secondary btn-delete" onclick="batchDeleteExecutions()" data-i18n="mcp.deleteSelected">批量删除</button>
                                    </div>
                                </div>
                                <div id="monitor-executions" class="monitor-table-container">
                                    <div class="monitor-empty" data-i18n="mcpMonitor.loading">加载中...</div>
                                </div>
                            </section>
                        </div>
                    </div>
                </div>

                <!-- MCP管理页面 -->
                <div id="page-mcp-management" class="page">
                    <div class="page-header">
                        <h2 data-i18n="mcp.managementTitle">MCP 管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="loadExternalMCPs()"><span data-i18n="common.refresh">刷新</span></button>
                        </div>
                    </div>
                    <div class="page-content">
                        <div class="mcp-management-layout">
                        <!-- MCP工具配置 -->
                        <div class="settings-section mcp-management-panel mcp-tools-panel" style="margin-bottom: 32px;">
                            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
                                <h3 style="margin: 0;" data-i18n="mcp.toolConfig">MCP 工具配置</h3>
                                <button class="btn-primary" onclick="saveToolsConfig()" data-i18n="mcp.saveToolConfig">保存工具配置</button>
                            </div>
                            <div class="tools-controls mcp-panel-body">
                                <div class="tools-actions">
                                    <button class="btn-secondary" onclick="selectAllTools()" data-i18n="mcp.selectAll">全选</button>
                                    <button class="btn-secondary" onclick="deselectAllTools()" data-i18n="mcp.deselectAll">全不选</button>
                                    <div class="tools-status-filter">
                                        <button class="btn-filter active" data-filter="" onclick="filterToolsByStatus('')" data-i18n="mcp.filterAll">全部</button>
                                        <button class="btn-filter" data-filter="true" onclick="filterToolsByStatus('true')" data-i18n="mcp.filterEnabled">已启用</button>
                                        <button class="btn-filter" data-filter="false" onclick="filterToolsByStatus('false')" data-i18n="mcp.filterDisabled">已停用</button>
                                    </div>
                                    <div class="search-box">
                                        <input type="text" id="tools-search" data-i18n="mcp.toolSearchPlaceholder" data-i18n-attr="placeholder" placeholder="搜索工具..." onkeypress="handleSearchKeyPress(event)" oninput="if(this.value.trim() === '') clearSearch()" />
                                        <button class="btn-search" onclick="searchTools()" data-i18n="common.search" data-i18n-attr="title" title="搜索">🔍</button>
                                    </div>
                                    <div class="tools-stats" id="tools-stats"></div>
                                </div>
                                <div id="tools-list" class="tools-list"></div>
                            </div>
                        </div>

                        <!-- 外部MCP配置 -->
                        <div class="settings-section mcp-management-panel mcp-external-panel">
                            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
                                <h3 style="margin: 0;" data-i18n="mcp.externalConfig">外部 MCP 配置</h3>
                                <button class="btn-primary" onclick="showAddExternalMCPModal()" data-i18n="mcp.addExternalMCP">添加外部MCP</button>
                            </div>
                            <div class="external-mcp-controls mcp-panel-body">
                                <div class="external-mcp-actions">
                                    <div class="external-mcp-stats" id="external-mcp-stats"></div>
                                </div>
                                <div id="external-mcp-list" class="external-mcp-list"></div>
                            </div>
                        </div>
                        </div>
                    </div>
                </div>

                <!-- 知识管理页面 -->
                <div id="page-knowledge-management" class="page">
                    <div class="page-header">
                        <h2 data-i18n="knowledge.title">知识管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="refreshKnowledgeBase()" data-i18n="common.refresh">刷新</button>
                            <button class="btn-secondary" onclick="rebuildKnowledgeIndex()" data-i18n="knowledge.rebuildIndex">重建索引</button>
                            <button class="btn-primary" onclick="showAddKnowledgeItemModal()" data-i18n="knowledge.addKnowledge">添加知识</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <div class="knowledge-controls">
                            <div class="knowledge-stats-bar" id="knowledge-stats">
                                <div class="knowledge-stat-item">
                                    <span class="knowledge-stat-label" data-i18n="knowledge.totalItems">总知识项</span>
                                    <span class="knowledge-stat-value">-</span>
                                </div>
                                <div class="knowledge-stat-item">
                                    <span class="knowledge-stat-label" data-i18n="knowledge.categories">分类数</span>
                                    <span class="knowledge-stat-value">-</span>
                                </div>
                                <div class="knowledge-stat-item">
                                    <span class="knowledge-stat-label" data-i18n="knowledgePage.totalContent">总内容</span>
                                    <span class="knowledge-stat-value">-</span>
                                </div>
                            </div>
                            <div id="knowledge-index-progress" style="display: none; margin-bottom: 16px;"></div>
                            <div class="knowledge-filters">
                                <label>
                                    <span data-i18n="knowledgePage.categoryFilter">分类筛选</span>
                                    <div class="custom-select-wrapper">
                                        <div class="custom-select" id="knowledge-category-filter-wrapper">
                                            <div class="custom-select-trigger" id="knowledge-category-filter-trigger">
                                                <span data-i18n="knowledgePage.all">全部</span>
                                                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                    <path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                                </svg>
                                            </div>
                                            <div class="custom-select-dropdown" id="knowledge-category-filter-dropdown">
                                                <div class="custom-select-option" data-value="" onclick="selectKnowledgeCategory('')" data-i18n="knowledgePage.all">全部</div>
                                            </div>
                                        </div>
                                    </div>
                                </label>
                                <div class="search-box">
                                    <input type="text" id="knowledge-search" data-i18n="knowledgePage.searchPlaceholder" data-i18n-attr="placeholder" placeholder="搜索知识..." oninput="handleKnowledgeSearchInput()" onkeydown="if(event.key==='Enter') searchKnowledgeItems()" />
                                    <button class="btn-search" onclick="searchKnowledgeItems()" data-i18n="common.search" data-i18n-attr="title" title="搜索">🔍</button>
                                </div>
                            </div>
                        </div>
                        <div id="knowledge-items-list" class="knowledge-items-list">
                            <div class="loading-spinner" data-i18n="knowledgePage.loading">加载中...</div>
                        </div>
                        <div id="knowledge-pagination"></div>
                    </div>
                </div>

                <!-- 知识检索历史页面 -->
                <div id="page-knowledge-retrieval-logs" class="page">
                    <div class="page-header">
                        <h2 data-i18n="knowledge.retrievalLogs">检索历史</h2>
                        <button class="btn-secondary" onclick="refreshRetrievalLogs()" data-i18n="common.refresh">刷新</button>
                    </div>
                    <div class="page-content">
                        <div class="retrieval-logs-controls">
                            <div class="retrieval-stats-bar" id="retrieval-stats">
                                <div class="retrieval-stat-item">
                                    <span class="retrieval-stat-label" data-i18n="retrievalLogs.totalRetrievals">总检索次数</span>
                                    <span class="retrieval-stat-value">-</span>
                                </div>
                                <div class="retrieval-stat-item">
                                    <span class="retrieval-stat-label" data-i18n="retrievalLogs.successRetrievals">成功检索</span>
                                    <span class="retrieval-stat-value">-</span>
                                </div>
                                <div class="retrieval-stat-item">
                                    <span class="retrieval-stat-label" data-i18n="retrievalLogs.successRate">成功率</span>
                                    <span class="retrieval-stat-value">-</span>
                                </div>
                                <div class="retrieval-stat-item">
                                    <span class="retrieval-stat-label" data-i18n="retrievalLogs.retrievedItems">检索到知识项</span>
                                    <span class="retrieval-stat-value">-</span>
                                </div>
                            </div>
                            <div class="retrieval-logs-filters">
                                <label>
                                    <span data-i18n="retrievalLogs.conversationId">对话ID</span>
                                    <input type="text" id="retrieval-logs-conversation-id" data-i18n="retrievalLogs.optionalConversation" data-i18n-attr="placeholder" placeholder="可选：筛选特定对话" />
                                </label>
                                <label>
                                    <span data-i18n="retrievalLogs.messageId">消息ID</span>
                                    <input type="text" id="retrieval-logs-message-id" data-i18n="retrievalLogs.optionalMessage" data-i18n-attr="placeholder" placeholder="可选：筛选特定消息" />
                                </label>
                                <button class="btn-secondary" onclick="filterRetrievalLogs()" data-i18n="retrievalLogs.filter">筛选</button>
                            </div>
                        </div>
                        <div id="retrieval-logs-list" class="retrieval-logs-list">
                            <div class="loading-spinner" data-i18n="retrievalLogs.loading">加载中...</div>
                        </div>
                    </div>
                </div>

                <!-- 信息收集页面 -->
                <div id="page-info-collect" class="page">
                    <div class="page-header">
                        <h2 data-i18n="infoCollectPage.title">信息收集</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="resetFofaForm()" data-i18n="infoCollectPage.reset">重置</button>
                            <button class="btn-primary" onclick="submitFofaSearch()" data-i18n="infoCollectPage.confirm">确定</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <div class="info-collect-panel">
                            <div class="info-collect-form">
                                <div class="form-group">
                                    <label for="fofa-query" data-i18n="infoCollectPage.fofaQuerySyntax">FOFA 查询语法</label>
                                    <textarea id="fofa-query" class="info-collect-query-input" rows="1" data-i18n="infoCollect.queryPlaceholder" data-i18n-attr="placeholder" placeholder='例如：app="Apache" && country="CN"'></textarea>
                                    <small class="form-hint" data-i18n="infoCollectPage.formHint">查询语法参考 FOFA 文档，支持 && / || / () 等。</small>
                                    <div class="info-collect-presets" aria-label="FOFA 查询示例" data-i18n="infoCollectPage.queryPresetsAria" data-i18n-attr="aria-label" data-i18n-skip-text="true">
                                        <button class="preset-chip" type="button" onclick="applyFofaQueryPreset('app=&quot;Apache&quot; &amp;&amp; country=&quot;CN&quot;')" data-i18n="infoCollectPage.presetApache" data-i18n-attr="title" data-i18n-title="infoCollectPage.fillExample" title="填入示例">Apache + 中国</button>
                                        <button class="preset-chip" type="button" onclick="applyFofaQueryPreset('title=&quot;登录&quot; &amp;&amp; country=&quot;CN&quot;')" data-i18n="infoCollectPage.presetLogin" data-i18n-attr="title" data-i18n-title="infoCollectPage.fillExample" title="填入示例">登录页 + 中国</button>
                                        <button class="preset-chip" type="button" onclick="applyFofaQueryPreset('domain=&quot;example.com&quot;')" data-i18n="infoCollectPage.presetDomain" data-i18n-attr="title" data-i18n-title="infoCollectPage.fillExample" title="填入示例">指定域名</button>
                                        <button class="preset-chip" type="button" onclick="applyFofaQueryPreset('ip=&quot;1.1.1.1&quot;')" data-i18n="infoCollectPage.presetIp" data-i18n-attr="title" data-i18n-title="infoCollectPage.fillExample" title="填入示例">指定 IP</button>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label for="fofa-nl" data-i18n="infoCollectPage.naturalLanguage">自然语言（AI 解析为 FOFA 语法）</label>
                                    <div class="info-collect-nl-row">
                                        <textarea id="fofa-nl" class="info-collect-query-input" rows="1" data-i18n="infoCollectPage.nlPlaceholder" data-i18n-attr="placeholder" placeholder="例如：找美国 Missouri 的 Apache 站点，标题包含 Home"></textarea>
                                        <button id="fofa-nl-parse-btn" class="btn-secondary" type="button" onclick="parseFofaNaturalLanguage()" data-i18n="infoCollectPage.parseBtn" data-i18n-attr="title" data-i18n-title="infoCollectPage.parseBtnTitle" title="将自然语言解析为 FOFA 查询语法">AI 解析</button>
                                    </div>
                                    <div id="fofa-nl-status" class="fofa-nl-status muted" style="display: none;" aria-live="polite"></div>
                                    <small class="form-hint" data-i18n="infoCollectPage.parseHint">解析后会弹窗展示 FOFA 语法（可编辑），确认无误后再填入查询框并执行查询。</small>
                                </div>
                                <div class="info-collect-form-row">
                                    <div class="form-group">
                                        <label for="fofa-size" data-i18n="infoCollectPage.returnCount">返回数量</label>
                                        <input type="number" id="fofa-size" min="1" max="10000" value="100" />
                                    </div>
                                    <div class="form-group">
                                        <label for="fofa-page" data-i18n="infoCollectPage.pageNum">页码</label>
                                        <input type="number" id="fofa-page" min="1" value="1" />
                                    </div>
                                    <div class="form-group">
                                        <label class="checkbox-label" style="margin-top: 24px;">
                                            <input type="checkbox" id="fofa-full" class="modern-checkbox" />
                                            <span class="checkbox-custom"></span>
                                            <span class="checkbox-text" data-i18n="infoCollectPage.fullLabel">full</span>
                                        </label>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label for="fofa-fields" data-i18n="infoCollectPage.returnFields">返回字段名（逗号分隔）</label>
                                    <input type="text" id="fofa-fields" value="host,ip,port,domain,title,protocol,country,province,city,server" />
                                    <div class="info-collect-presets" aria-label="FOFA 字段模板" data-i18n="infoCollectPage.fieldsPresetsAria" data-i18n-attr="aria-label" data-i18n-skip-text="true">
                                        <button class="preset-chip" type="button" onclick="applyFofaFieldsPreset('host,ip,port,domain')" data-i18n="infoCollectPage.minFields" data-i18n-attr="title" data-i18n-title="infoCollectPage.minFieldsTitle" title="适合快速导出目标">最小字段</button>
                                        <button class="preset-chip" type="button" onclick="applyFofaFieldsPreset('host,title,ip,port,domain,protocol,server,icp,country,province,city')" data-i18n="infoCollectPage.webCommon" data-i18n-attr="title" data-i18n-title="infoCollectPage.webCommonTitle" title="适合浏览和筛选">Web 常用</button>
                                        <button class="preset-chip" type="button" onclick="applyFofaFieldsPreset('host,ip,port,domain,title,protocol,country,province,city,server,as_number,as_organization,icp,header,banner')" data-i18n="infoCollectPage.intelEnhanced" data-i18n-attr="title" data-i18n-title="infoCollectPage.intelEnhancedTitle" title="更偏指纹/情报">情报增强</button>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="info-collect-results">
                            <div class="info-collect-results-header">
                                <div class="info-collect-results-header-left">
                                    <div class="info-collect-results-title" data-i18n="infoCollectPage.queryResults">查询结果</div>
                                    <div class="info-collect-results-meta" id="fofa-results-meta">-</div>
                                </div>
                                <div class="info-collect-results-toolbar" aria-label="结果工具条" data-i18n="infoCollectPage.resultsToolbarAria" data-i18n-attr="aria-label" data-i18n-skip-text="true">
                                    <div class="info-collect-selected" id="fofa-selected-meta" data-i18n="infoCollectPage.selectedRowsZero">已选择 0 条</div>
                                    <button class="btn-secondary btn-small" type="button" onclick="toggleFofaColumnsPanel()" data-i18n="infoCollectPage.showHideColumns" data-i18n-attr="title" title="显示/隐藏字段"><span data-i18n="infoCollectPage.columns">列</span></button>
                                    <button class="btn-secondary btn-small" type="button" onclick="exportFofaResults('csv')" data-i18n="infoCollectPage.exportCsvTitle" data-i18n-attr="title" title="导出当前结果为 CSV（UTF-8，兼容中文）"><span data-i18n="infoCollectPage.exportCsv">导出 CSV</span></button>
                                    <button class="btn-secondary btn-small" type="button" onclick="exportFofaResults('json')" data-i18n="infoCollectPage.exportJsonTitle" data-i18n-attr="title" title="导出当前结果为 JSON"><span data-i18n="infoCollectPage.exportJson">导出 JSON</span></button>
                                    <button class="btn-secondary btn-small" type="button" onclick="exportFofaResults('xlsx')" data-i18n="infoCollectPage.exportXlsxTitle" data-i18n-attr="title" title="导出当前结果为 Excel"><span data-i18n="infoCollectPage.exportXlsx">导出 XLSX</span></button>
                                    <button class="btn-primary btn-small" type="button" onclick="batchScanSelectedFofaRows()" data-i18n="infoCollectPage.batchScanTitle" data-i18n-attr="title" title="将所选行创建为批量任务队列"><span data-i18n="infoCollectPage.batchScan">批量扫描</span></button>
                                </div>
                            </div>
                            <div class="info-collect-results-table-wrap">
                                <!-- 字段显示/隐藏面板 -->
                                <div id="fofa-columns-panel" class="info-collect-columns-panel" style="display: none;">
                                    <div class="info-collect-columns-panel-header">
                                        <div class="info-collect-columns-title" data-i18n="infoCollectPage.showColumns">显示字段</div>
                                        <div class="info-collect-columns-actions">
                                            <button class="btn-secondary btn-small" type="button" onclick="showAllFofaColumns()" data-i18n="infoCollectPage.columnsPanelAll">全选</button>
                                            <button class="btn-secondary btn-small" type="button" onclick="hideAllFofaColumns()" data-i18n="infoCollectPage.columnsPanelNone">全不选</button>
                                            <button class="btn-secondary btn-small" type="button" onclick="closeFofaColumnsPanel()" data-i18n="infoCollectPage.columnsPanelClose">关闭</button>
                                        </div>
                                    </div>
                                    <div id="fofa-columns-list" class="info-collect-columns-list"></div>
                                </div>
                                <table class="info-collect-table">
                                    <thead id="fofa-results-thead"></thead>
                                    <tbody id="fofa-results-tbody">
                                        <tr><td class="muted" style="padding: 16px;" data-i18n="common.noData">暂无数据</td></tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 项目管理页面 -->
                <div id="page-projects" class="page projects-page">
                    <div class="page-header">
                        <h2 data-i18n="projects.title">项目管理</h2>
                        <div class="page-header-actions">
                            <label class="projects-show-archived-label"><input type="checkbox" id="projects-show-archived" onchange="loadProjectsList()"> <span data-i18n="projects.showArchived">显示已归档</span></label>
                            <button class="btn-secondary" type="button" onclick="loadProjectsList()" data-i18n="common.refresh">刷新</button>
                            <button class="btn-primary" type="button" onclick="showNewProjectModal()" data-i18n="projects.newProjectCta">+ 新建项目</button>
                        </div>
                    </div>
                    <div class="page-content projects-page-layout">
                        <aside class="projects-sidebar-card">
                            <div class="projects-sidebar-head">
                                <span class="projects-sidebar-title" data-i18n="projects.projectList">项目列表</span>
                                <span class="projects-sidebar-count" id="projects-list-count">0</span>
                            </div>
                            <div class="projects-sidebar-search">
                                <input type="search" id="projects-list-search" class="form-input" placeholder="搜索项目…" oninput="filterProjectsList()" autocomplete="off" data-i18n="projects.searchProjectsPlaceholder" data-i18n-attr="placeholder">
                            </div>
                            <div id="projects-list" class="projects-list"></div>
                        </aside>
                        <main class="projects-detail" id="projects-detail-main">
                            <div class="projects-detail-placeholder" id="projects-detail-placeholder">
                                <h3 data-i18n="projects.selectOrCreateTitle">选择或创建项目</h3>
                                <p data-i18n="projects.selectOrCreateHint">项目用于跨对话共享「事实黑板」：目标、环境、认证等信息会在绑定项目的对话中自动注入。</p>
                                <button class="btn-primary" type="button" onclick="showNewProjectModal()" data-i18n="projects.createFirstProject">创建第一个项目</button>
                            </div>
                            <div class="projects-detail-inner" id="projects-detail-inner" hidden>
                                <header class="projects-detail-header">
                                    <div class="projects-detail-header-main">
                                        <div class="projects-detail-title-row">
                                            <h3 id="projects-detail-title" class="projects-detail-title" data-i18n="projects.defaultProjectName">项目</h3>
                                            <span id="projects-detail-status" class="projects-status-pill projects-status-pill--active" data-i18n="projects.statusActive">进行中</span>
                                        </div>
                                        <p id="projects-detail-meta" class="projects-detail-meta"></p>
                                        <p id="projects-detail-desc" class="projects-detail-desc"></p>
                                        <div class="projects-detail-stats" id="projects-detail-stats">
                                            <span class="projects-stat-chip" id="project-stat-facts">0 条事实</span>
                                            <span class="projects-stat-chip" id="project-stat-vulns">0 个漏洞</span>
                                            <span class="projects-stat-chip" id="project-stat-conversations">0 个对话</span>
                                            <span class="projects-stat-chip projects-stat-chip--warn" id="project-stat-sparse" hidden>0 待补全</span>
                                        </div>
                                    </div>
                                    <div class="projects-detail-header-actions">
                                        <button type="button" class="btn-secondary btn-small" onclick="openVulnerabilitiesForProject()" data-i18n="projects.vulnerabilityManagement">漏洞管理</button>
                                        <button type="button" class="btn-primary btn-small" onclick="showAddFactModal()" data-i18n="projects.addFactCta">+ 添加事实</button>
                                    </div>
                                </header>
                                <nav class="projects-tabs" role="tablist">
                                    <button type="button" id="project-tab-facts" class="projects-tab is-active" role="tab" onclick="switchProjectTab('facts')" data-i18n="projects.tabFacts">事实黑板</button>
                                    <button type="button" id="project-tab-conversations" class="projects-tab" role="tab" onclick="switchProjectTab('conversations')" data-i18n="projects.tabConversations">关联对话</button>
                                    <button type="button" id="project-tab-vulns" class="projects-tab" role="tab" onclick="switchProjectTab('vulns')" data-i18n="projects.tabVulns">关联漏洞</button>
                                    <button type="button" id="project-tab-settings" class="projects-tab" role="tab" onclick="switchProjectTab('settings')" data-i18n="projects.tabSettings">设置</button>
                                </nav>
                                <div id="project-panel-facts" class="projects-panel" role="tabpanel">
                                    <div class="projects-fact-toolbar">
                                        <p class="projects-fact-toolbar-hint" role="note">
                                            <svg class="projects-fact-toolbar-hint-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
                                                <circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2"/>
                                                <path d="M12 10v6M12 8h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                            </svg>
                                            <span data-i18n="projects.factToolbarHint">索引仅含 key 与摘要（须含「什么 + 在哪 + 如何验证」）；攻击链 / POC 写在 body，Agent 通过 get_project_fact 复现</span>
                                        </p>
                                        <div class="projects-fact-toolbar-filters" role="search">
                                            <label class="projects-fact-filter-field projects-fact-filter-field--search">
                                                <span class="sr-only" data-i18n="projects.searchFactsSr">搜索事实</span>
                                                <svg class="projects-fact-search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
                                                    <circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="2"/>
                                                    <path d="M20 20L16 16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                                </svg>
                                                <input type="search" id="project-facts-search" placeholder="搜索 key、摘要、body…" oninput="debouncedLoadProjectFacts()" autocomplete="off" data-i18n="projects.searchFactsPlaceholder" data-i18n-attr="placeholder">
                                            </label>
                                            <label class="projects-fact-filter-field">
                                                <span class="projects-fact-filter-label" data-i18n="projects.category">分类</span>
                                                <select id="project-facts-filter-category" onchange="loadProjectFacts()">
                                                    <option value="" data-i18n="projects.all">全部</option>
                                                    <option value="target">target</option>
                                                    <option value="auth">auth</option>
                                                    <option value="infra">infra</option>
                                                    <option value="business">business</option>
                                                    <option value="finding">finding</option>
                                                    <option value="chain">chain</option>
                                                    <option value="exploit">exploit</option>
                                                    <option value="poc">poc</option>
                                                    <option value="note">note</option>
                                                </select>
                                            </label>
                                            <label class="projects-fact-filter-field">
                                                <span class="projects-fact-filter-label" data-i18n="projects.confidence">置信度</span>
                                                <select id="project-facts-filter-confidence" onchange="loadProjectFacts()">
                                                    <option value="" data-i18n="projects.all">全部</option>
                                                    <option value="confirmed" data-i18n="projects.confidenceConfirmed">已确认</option>
                                                    <option value="tentative" data-i18n="projects.confidenceTentative">待确认</option>
                                                    <option value="deprecated" data-i18n="projects.confidenceDeprecated">已废弃</option>
                                                </select>
                                            </label>
                                            <div class="projects-fact-filter-toggles" role="group" aria-label="显示选项" data-i18n="projects.displayOptions" data-i18n-attr="aria-label">
                                                <label class="projects-fact-toggle">
                                                    <input type="checkbox" id="project-facts-filter-sparse" onchange="loadProjectFacts()">
                                                    <span data-i18n="projects.sparseOnly">仅待补全</span>
                                                </label>
                                                <label class="projects-fact-toggle">
                                                    <input type="checkbox" id="project-facts-filter-hide-deprecated" checked onchange="loadProjectFacts()">
                                                    <span data-i18n="projects.hideDeprecated">隐藏废弃</span>
                                                </label>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="projects-table-wrap">
                                        <table class="data-table data-table--projects">
                                            <thead><tr><th>Key</th><th data-i18n="projects.category">分类</th><th data-i18n="projects.summary">摘要</th><th>Body</th><th data-i18n="projects.confidence">置信度</th><th data-i18n="projects.updated">更新</th><th class="col-actions" data-i18n="common.actions">操作</th></tr></thead>
                                            <tbody id="project-facts-tbody"></tbody>
                                        </table>
                                    </div>
                                </div>
                                <div id="project-panel-conversations" class="projects-panel" role="tabpanel" hidden>
                                    <div class="projects-panel-toolbar projects-panel-toolbar--hint">
                                        <p class="projects-fact-toolbar-hint" role="note">
                                            <svg class="projects-fact-toolbar-hint-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
                                                <circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2"/>
                                                <path d="M12 10v6M12 8h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                            </svg>
                                            <span data-i18n="projects.boundConversationsHint">绑定到本项目的对话；点击可打开会话</span>
                                        </p>
                                    </div>
                                    <div class="projects-table-wrap">
                                        <table class="data-table data-table--projects">
                                            <thead><tr><th data-i18n="projects.titleLabel">标题</th><th data-i18n="projects.updated">更新</th><th class="col-actions" data-i18n="common.actions">操作</th></tr></thead>
                                            <tbody id="project-conversations-tbody"></tbody>
                                        </table>
                                    </div>
                                </div>
                                <div id="project-panel-vulns" class="projects-panel" role="tabpanel" hidden>
                                    <div class="projects-fact-toolbar">
                                        <div class="projects-vuln-toolbar-top">
                                            <p class="projects-fact-toolbar-hint" role="note">
                                                <svg class="projects-fact-toolbar-hint-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
                                                    <circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2"/>
                                                    <path d="M12 10v6M12 8h.01" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                                </svg>
                                                <span data-i18n="projects.projectVulnSummaryHint">本项目下记录的漏洞汇总</span>
                                            </p>
                                            <button type="button" class="btn-secondary btn-small" onclick="openVulnerabilitiesForProject()" data-i18n="projects.viewInVulnerabilityManagement">在漏洞管理中查看</button>
                                        </div>
                                        <div class="projects-fact-toolbar-filters" role="search">
                                            <label class="projects-fact-filter-field projects-fact-filter-field--search">
                                                <span class="sr-only" data-i18n="projects.searchVulnsSr">搜索漏洞</span>
                                                <svg class="projects-fact-search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
                                                    <circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="2"/>
                                                    <path d="M20 20L16 16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                                </svg>
                                                <input type="search" id="project-vulns-search" placeholder="搜索标题、描述、类型、目标…" oninput="debouncedLoadProjectVulnerabilities()" autocomplete="off" data-i18n="projects.searchVulnsPlaceholder" data-i18n-attr="placeholder">
                                            </label>
                                            <label class="projects-fact-filter-field">
                                                <span class="projects-fact-filter-label" data-i18n="projects.severity">严重度</span>
                                                <select id="project-vulns-filter-severity" onchange="loadProjectVulnerabilities()">
                                                    <option value="" data-i18n="projects.all">全部</option>
                                                    <option value="critical">critical</option>
                                                    <option value="high">high</option>
                                                    <option value="medium">medium</option>
                                                    <option value="low">low</option>
                                                    <option value="info">info</option>
                                                </select>
                                            </label>
                                            <label class="projects-fact-filter-field">
                                                <span class="projects-fact-filter-label" data-i18n="projects.status">状态</span>
                                                <select id="project-vulns-filter-status" onchange="loadProjectVulnerabilities()">
                                                    <option value="" data-i18n="projects.all">全部</option>
                                                    <option value="open" data-i18n="vulnerabilityPage.statusOpen">待处理</option>
                                                    <option value="confirmed" data-i18n="vulnerabilityPage.statusConfirmed">已确认</option>
                                                    <option value="fixed" data-i18n="vulnerabilityPage.statusFixed">已修复</option>
                                                    <option value="false_positive" data-i18n="vulnerabilityPage.statusFalsePositive">误报</option>
                                                </select>
                                            </label>
                                        </div>
                                    </div>
                                    <div class="projects-table-wrap">
                                        <table class="data-table data-table--projects">
                                            <thead><tr><th data-i18n="projects.titleLabel">标题</th><th data-i18n="projects.severity">严重度</th><th data-i18n="projects.status">状态</th><th class="col-actions" data-i18n="common.actions">操作</th></tr></thead>
                                            <tbody id="project-vulns-tbody"></tbody>
                                        </table>
                                    </div>
                                </div>
                                <div id="project-panel-settings" class="projects-panel projects-panel--settings" role="tabpanel" hidden>
                                    <div class="projects-settings-layout">
                                        <header class="projects-settings-intro">
                                            <div class="projects-settings-intro-text">
                                                <h4 class="projects-settings-intro-title" data-i18n="projects.settingsIntroTitle">项目设置</h4>
                                                <p class="projects-settings-intro-hint" data-i18n="projects.settingsIntroHint">配置项目元数据与 Agent 授权边界，保存后即时生效于绑定对话。</p>
                                            </div>
                                        </header>
                                        <div class="projects-settings-grid">
                                            <section class="projects-settings-card projects-settings-card--basic">
                                                <div class="projects-settings-card-head">
                                                    <div class="projects-settings-card-head-left">
                                                        <span class="projects-settings-icon projects-settings-icon--blue" aria-hidden="true">
                                                            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
                                                        </span>
                                                        <div>
                                                            <h4 class="projects-settings-card-title" data-i18n="projects.basicInfoTitle">基本信息</h4>
                                                            <p class="projects-settings-card-hint" data-i18n="projects.basicInfoHint">名称与描述会显示在项目详情中</p>
                                                        </div>
                                                    </div>
                                                </div>
                                                <div class="projects-settings-card-body">
                                                    <div class="projects-form-row projects-form-row--2">
                                                        <div class="projects-form-field">
                                                            <label for="project-edit-name" data-i18n="projects.projectName">项目名称</label>
                                                            <input type="text" id="project-edit-name" class="form-input" placeholder="例如：某客户 Web 渗透" data-i18n="projects.projectNamePlaceholder" data-i18n-attr="placeholder">
                                                        </div>
                                                        <div class="projects-form-field">
                                                            <label for="project-edit-status" data-i18n="projects.status">状态</label>
                                                            <div class="projects-status-select-wrap">
                                                                <select id="project-edit-status" class="form-input projects-status-select">
                                                                    <option value="active" data-i18n="projects.statusActive">进行中</option>
                                                                    <option value="archived" data-i18n="projects.statusArchived">已归档</option>
                                                                </select>
                                                            </div>
                                                        </div>
                                                    </div>
                                                    <div class="projects-form-field">
                                                        <label class="projects-filter-check projects-pin-toggle">
                                                            <input type="checkbox" id="project-edit-pinned"> <span data-i18n="projects.pinProject">置顶项目（列表优先显示）</span>
                                                        </label>
                                                    </div>
                                                    <div class="projects-form-field">
                                                        <label for="project-edit-description" data-i18n="projects.projectDescription">描述</label>
                                                        <textarea id="project-edit-description" class="form-input" rows="3" placeholder="测试目标、授权范围、联系人、注意事项…" data-i18n="projects.editDescriptionPlaceholder" data-i18n-attr="placeholder"></textarea>
                                                    </div>
                                                </div>
                                            </section>
                                            <section class="projects-settings-card projects-settings-card--scope">
                                                <div class="projects-settings-card-head">
                                                    <div class="projects-settings-card-head-left">
                                                        <span class="projects-settings-icon projects-settings-icon--violet" aria-hidden="true">
                                                            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
                                                        </span>
                                                        <div>
                                                            <h4 class="projects-settings-card-title" data-i18n="projects.scopeTitle">测试范围</h4>
                                                            <p class="projects-settings-card-hint" data-i18n="projects.scopeHint">JSON 格式，供 Agent 理解授权边界与目标资产</p>
                                                        </div>
                                                    </div>
                                                    <div class="projects-scope-toolbar">
                                                        <button type="button" class="btn-ghost btn-small" onclick="formatProjectScopeJson()" title="格式化 JSON" data-i18n="projects.formatJson" data-i18n-attr="title">格式化</button>
                                                        <button type="button" class="btn-ghost btn-small" onclick="insertProjectScopeExample()" title="插入示例" data-i18n="projects.example" data-i18n-attr="title">示例</button>
                                                    </div>
                                                </div>
                                                <div class="projects-settings-card-body projects-settings-card-body--fill">
                                                    <div class="projects-scope-editor">
                                                        <label for="project-edit-scope" class="sr-only" data-i18n="projects.scopeJsonLabel">范围 JSON</label>
                                                        <textarea id="project-edit-scope" class="form-input form-input--mono projects-scope-textarea" spellcheck="false" placeholder='{"targets":["https://example.com"],"exclude":["*.cdn.example.com"]}'></textarea>
                                                    </div>
                                                    <p class="projects-scope-footnote" data-i18n="projects.scopeFootnote">支持 targets、exclude、notes 等字段，留空表示不限制范围。</p>
                                                </div>
                                            </section>
                                        </div>
                                        <section class="projects-settings-card projects-settings-card--danger">
                                            <div class="projects-settings-danger-main">
                                                <span class="projects-settings-icon projects-settings-icon--red" aria-hidden="true">
                                                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
                                                </span>
                                                <div>
                                                    <h4 class="projects-settings-card-title" data-i18n="projects.dangerZoneTitle">危险操作</h4>
                                                    <p class="projects-settings-card-hint" data-i18n="projects.dangerZoneHint">归档后需在列表勾选「显示已归档」才能查看；删除将清除全部事实且不可恢复。</p>
                                                </div>
                                            </div>
                                            <div class="projects-settings-danger-actions">
                                                <button class="btn-secondary btn-small" type="button" onclick="archiveCurrentProject()" data-i18n="projects.archiveRestore">归档 / 恢复</button>
                                                <button class="btn-secondary btn-small btn-danger-outline" type="button" onclick="deleteCurrentProject()" data-i18n="projects.deleteProject">删除项目</button>
                                            </div>
                                        </section>
                                    </div>
                                    <footer class="projects-settings-footer">
                                        <span class="projects-settings-footer-hint" data-i18n="projects.saveChangesHint">修改后请点击保存以同步到服务器</span>
                                        <button class="btn-primary" type="button" onclick="saveProjectSettings()">
                                            <span data-i18n="projects.saveSettings">保存更改</span>
                                        </button>
                                    </footer>
                                </div>
                            </div>
                        </main>
                    </div>
                </div>
                <!-- 漏洞管理页面 -->
                <div id="page-vulnerabilities" class="page">
                    <div class="page-header">
                        <h2 data-i18n="vulnerability.title">漏洞管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="exportVulnerabilityReports()" data-i18n="vulnerabilityPage.batchExport">批量导出</button>
                            <button class="btn-secondary" onclick="refreshVulnerabilities()" data-i18n="common.refresh">刷新</button>
                            <button class="btn-primary" onclick="showAddVulnerabilityModal()" data-i18n="vulnerability.addVuln">添加漏洞</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <!-- 统计看板：点击卡片筛选严重度，与下方下拉/地址栏 hash 同步 -->
                        <div class="vulnerability-dashboard" id="vulnerability-dashboard">
                            <div class="dashboard-stats" id="vulnerability-stat-cards" role="group" aria-label="漏洞严重度统计">
                                <div class="stat-card stat-card-total is-clickable is-active" data-severity="" role="button" tabindex="0"
                                     data-i18n="vulnerabilityPage.statClickAll" data-i18n-attr="title" title="查看全部（清除严重度筛选）">
                                    <div class="stat-label" data-i18n="vulnerabilityPage.statTotal">总漏洞数</div>
                                    <div class="stat-value" id="stat-total">-</div>
                                    <div class="stat-stacked-bar" id="stat-stacked-bar" aria-hidden="true">
                                        <span class="stat-stacked-seg critical" data-sev="critical"></span>
                                        <span class="stat-stacked-seg high" data-sev="high"></span>
                                        <span class="stat-stacked-seg medium" data-sev="medium"></span>
                                        <span class="stat-stacked-seg low" data-sev="low"></span>
                                        <span class="stat-stacked-seg info" data-sev="info"></span>
                                    </div>
                                </div>
                                <div class="stat-card stat-critical is-clickable" data-severity="critical" role="button" tabindex="0"
                                     data-i18n="vulnerabilityPage.statClickFilter" data-i18n-attr="title" title="点击按此严重度筛选；再次点击清除">
                                    <div class="stat-label" data-i18n="dashboard.severityCritical">严重</div>
                                    <div class="stat-value" id="stat-critical">-</div>
                                    <div class="stat-pct" id="stat-critical-pct" aria-hidden="true">—</div>
                                </div>
                                <div class="stat-card stat-high is-clickable" data-severity="high" role="button" tabindex="0"
                                     data-i18n="vulnerabilityPage.statClickFilter" data-i18n-attr="title" title="点击按此严重度筛选；再次点击清除">
                                    <div class="stat-label" data-i18n="dashboard.severityHigh">高危</div>
                                    <div class="stat-value" id="stat-high">-</div>
                                    <div class="stat-pct" id="stat-high-pct" aria-hidden="true">—</div>
                                </div>
                                <div class="stat-card stat-medium is-clickable" data-severity="medium" role="button" tabindex="0"
                                     data-i18n="vulnerabilityPage.statClickFilter" data-i18n-attr="title" title="点击按此严重度筛选；再次点击清除">
                                    <div class="stat-label" data-i18n="dashboard.severityMedium">中危</div>
                                    <div class="stat-value" id="stat-medium">-</div>
                                    <div class="stat-pct" id="stat-medium-pct" aria-hidden="true">—</div>
                                </div>
                                <div class="stat-card stat-low is-clickable" data-severity="low" role="button" tabindex="0"
                                     data-i18n="vulnerabilityPage.statClickFilter" data-i18n-attr="title" title="点击按此严重度筛选；再次点击清除">
                                    <div class="stat-label" data-i18n="dashboard.severityLow">低危</div>
                                    <div class="stat-value" id="stat-low">-</div>
                                    <div class="stat-pct" id="stat-low-pct" aria-hidden="true">—</div>
                                </div>
                                <div class="stat-card stat-info is-clickable" data-severity="info" role="button" tabindex="0"
                                     data-i18n="vulnerabilityPage.statClickFilter" data-i18n-attr="title" title="点击按此严重度筛选；再次点击清除">
                                    <div class="stat-label" data-i18n="dashboard.severityInfo">信息</div>
                                    <div class="stat-value" id="stat-info">-</div>
                                    <div class="stat-pct" id="stat-info-pct" aria-hidden="true">—</div>
                                </div>
                            </div>
                        </div>

                        <!-- 筛选 -->
                        <div class="vulnerability-controls" id="vulnerability-filter-panel">
                            <div class="vulnerability-filter-toolbar">
                                <div class="vulnerability-filter-primary">
                                    <label class="vulnerability-filter-field vulnerability-filter-field--grow vulnerability-search-wrap">
                                        <span class="sr-only" data-i18n="vulnerabilityPage.searchKeyword">关键词搜索</span>
                                        <svg class="vulnerability-search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
                                            <circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="2"/>
                                            <path d="M20 20L16 16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                        </svg>
                                        <input type="search" id="vulnerability-search-filter" autocomplete="off"
                                            data-i18n="vulnerabilityPage.searchKeyword" data-i18n-attr="placeholder" placeholder="搜索标题、描述、类型、目标…" />
                                    </label>
                                    <label class="vulnerability-filter-field vulnerability-filter-field--project">
                                        <span class="sr-only">项目</span>
                                        <select id="vulnerability-project-filter" title="按项目筛选" onchange="scheduleVulnerabilityFilterApply(true)">
                                            <option value="">全部项目</option>
                                        </select>
                                    </label>
                                    <label class="vulnerability-filter-field vulnerability-filter-field--status">
                                        <span class="sr-only" data-i18n="vulnerabilityPage.status">状态</span>
                                        <select id="vulnerability-status-filter" data-i18n-attr="title" title="状态">
                                            <option value="" data-i18n="knowledgePage.all">全部状态</option>
                                            <option value="open" data-i18n="vulnerabilityPage.statusOpen">待处理</option>
                                            <option value="confirmed" data-i18n="vulnerabilityPage.statusConfirmed">已确认</option>
                                            <option value="fixed" data-i18n="vulnerabilityPage.statusFixed">已修复</option>
                                            <option value="false_positive" data-i18n="vulnerabilityPage.statusFalsePositive">误报</option>
                                        </select>
                                    </label>
                                    <div class="vulnerability-filter-actions">
                                        <div class="vulnerability-more-filters-anchor">
                                            <button type="button" class="btn-secondary vulnerability-more-filters-btn" id="vulnerability-more-filters-btn"
                                                aria-expanded="false" aria-haspopup="dialog" aria-controls="vulnerability-more-filters-popover">
                                                <span data-i18n="vulnerabilityPage.moreFilters">更多筛选</span>
                                                <span class="vulnerability-filter-advanced-badge" id="vulnerability-advanced-badge" hidden></span>
                                            </button>
                                            <div class="vulnerability-more-filters-popover" id="vulnerability-more-filters-popover" hidden role="dialog"
                                                aria-labelledby="vulnerability-more-filters-title">
                                                <p class="vulnerability-more-filters-popover-title" id="vulnerability-more-filters-title" data-i18n="vulnerabilityPage.moreFilters">更多筛选</p>
                                                <div class="vulnerability-more-filters-popover-body">
                                                    <label class="vulnerability-filter-field vulnerability-filter-field--full">
                                                        <span data-i18n="vulnerabilityPage.vulnId">漏洞 ID</span>
                                                        <input type="text" id="vulnerability-exact-id-filter"
                                                            data-i18n="vulnerabilityPage.filterExactId" data-i18n-attr="placeholder" placeholder="精确匹配漏洞 ID" />
                                                    </label>
                                                    <label class="vulnerability-filter-field">
                                                        <span data-i18n="vulnerabilityPage.conversationId">会话 ID</span>
                                                        <input type="text" id="vulnerability-conversation-filter" list="vulnerability-conversation-suggestions"
                                                            data-i18n="vulnerabilityPage.filterConversation" data-i18n-attr="placeholder" placeholder="筛选特定会话" />
                                                    </label>
                                                    <label class="vulnerability-filter-field">
                                                        <span data-i18n="vulnerabilityPage.taskOrQueueId">任务 / 队列 ID</span>
                                                        <input type="text" id="vulnerability-task-filter" list="vulnerability-task-suggestions"
                                                            data-i18n="vulnerabilityPage.filterTaskOrQueue" data-i18n-attr="placeholder" placeholder="筛选任务或队列 ID" />
                                                    </label>
                                                    <label class="vulnerability-filter-field">
                                                        <span data-i18n="vulnerabilityPage.conversationTag">对话标签</span>
                                                        <input type="text" id="vulnerability-conversation-tag-filter" list="vulnerability-conversation-tag-suggestions"
                                                            data-i18n="vulnerabilityPage.filterConversationTag" data-i18n-attr="placeholder" placeholder="筛选对话标签" />
                                                    </label>
                                                    <label class="vulnerability-filter-field">
                                                        <span data-i18n="vulnerabilityPage.taskTag">任务标签</span>
                                                        <input type="text" id="vulnerability-task-tag-filter" list="vulnerability-task-tag-suggestions"
                                                            data-i18n="vulnerabilityPage.filterTaskTag" data-i18n-attr="placeholder" placeholder="筛选任务标签" />
                                                    </label>
                                                </div>
                                                <div class="vulnerability-more-filters-popover-footer">
                                                    <button type="button" class="btn-secondary" id="vulnerability-more-filters-reset" data-i18n="vulnerabilityPage.clearAdvanced">清空</button>
                                                    <button type="button" class="btn-primary" id="vulnerability-more-filters-apply" data-i18n="vulnerabilityPage.applyFilters">应用</button>
                                                </div>
                                            </div>
                                        </div>
                                        <button type="button" class="vulnerability-filter-clear-btn" id="vulnerability-filter-clear-btn"
                                            onclick="clearVulnerabilityFilters()" hidden data-i18n="vulnerabilityPage.clearAll">重置全部</button>
                                    </div>
                                </div>
                                <select id="vulnerability-severity-filter" class="vulnerability-severity-sync" hidden aria-hidden="true" tabindex="-1">
                                    <option value=""></option>
                                    <option value="critical">critical</option>
                                    <option value="high">high</option>
                                    <option value="medium">medium</option>
                                    <option value="low">low</option>
                                    <option value="info">info</option>
                                </select>
                            </div>
                            <div class="vulnerability-filter-chips" id="vulnerability-filter-chips" hidden>
                                <span class="vulnerability-filter-chips-label" data-i18n="vulnerabilityPage.activeFilters">已选条件</span>
                                <div class="vulnerability-filter-chips-list" id="vulnerability-filter-chips-list" role="list"></div>
                            </div>
                            <datalist id="vulnerability-conversation-suggestions"></datalist>
                            <datalist id="vulnerability-task-suggestions"></datalist>
                            <datalist id="vulnerability-conversation-tag-suggestions"></datalist>
                            <datalist id="vulnerability-task-tag-suggestions"></datalist>
                        </div>

                        <!-- 漏洞列表 -->
                        <div id="vulnerabilities-list" class="vulnerabilities-list">
                            <div class="loading-spinner" data-i18n="vulnerabilityPage.loading">加载中...</div>
                        </div>
                        
                        <!-- 分页控件 -->
                        <div id="vulnerability-pagination" class="pagination-container pagination-fixed"></div>
                    </div>
                </div>

                <!-- WebShell 管理页面 -->
                <div id="page-webshell" class="page">
                    <div class="page-header">
                        <h2 data-i18n="webshell.title">WebShell 管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-primary" onclick="showAddWebshellModal()" data-i18n="webshell.addConnection">添加连接</button>
                        </div>
                    </div>
                    <div class="page-content webshell-page-content">
                        <div class="webshell-layout">
                            <div id="webshell-sidebar" class="webshell-sidebar">
                                <div class="webshell-sidebar-header" data-i18n="webshell.connections">连接列表</div>
                                <div class="webshell-conn-search">
                                    <input type="text"
                                           id="webshell-conn-search"
                                           class="form-control webshell-conn-search-input"
                                           data-i18n="webshell.searchPlaceholder"
                                           data-i18n-attr="placeholder"
                                           placeholder="搜索连接..." />
                                </div>
                                <div class="webshell-sidebar-tools">
                                    <button type="button" class="btn-ghost btn-sm" id="webshell-batch-probe-btn" data-i18n="webshell.batchProbe">一键批量探活</button>
                                </div>
                                <div id="webshell-list" class="webshell-list">
                                    <div class="webshell-empty" data-i18n="webshell.noConnections">暂无连接，请点击「添加连接」</div>
                                </div>
                            </div>
                            <div id="webshell-resize-handle" class="webshell-resize-handle" title="拖拽调整宽度"></div>
                            <div class="webshell-main">
                                <div id="webshell-workspace" class="webshell-workspace">
                                    <div class="webshell-workspace-placeholder" data-i18n="webshell.selectOrAdd">请从左侧选择连接，或添加新的 WebShell 连接</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 对话附件 / 文件管理 -->
                <div id="page-chat-files" class="page">
                    <div class="page-header">
                        <h2 data-i18n="chatFilesPage.title">文件管理</h2>
                        <div class="page-header-actions">
                            <button type="button" class="btn-primary" id="chat-files-header-upload-btn" onclick="chatFilesOpenUploadPicker()" data-i18n="chatFilesPage.upload">上传文件</button>
                            <input type="file" id="chat-files-upload-input" style="display:none" onchange="onChatFilesUploadPick(event)" />
                            <button type="button" class="btn-secondary" id="chat-files-refresh-btn" onclick="loadChatFilesPage()" data-i18n="common.refresh">刷新</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <p class="chat-files-intro" data-i18n="chatFilesPage.intro">管理在对话中上传的文件。需要让 AI 引用某文件时，在列表中点击「复制路径」，到对话里粘贴即可。</p>
                        <div class="tasks-filters chat-files-filters">
                            <label>
                                <span data-i18n="chatFilesPage.conversationFilter">会话 ID</span>
                                <input type="text" id="chat-files-filter-conv" class="form-control" data-i18n="chatFilesPage.conversationPlaceholder" data-i18n-attr="placeholder" placeholder="留空表示全部" onkeydown="if(event.key==='Enter') loadChatFilesPage()" />
                            </label>
                            <label style="flex:1;min-width:180px;max-width:360px;">
                                <span data-i18n="chatFilesPage.searchName">文件名</span>
                                <input type="text" id="chat-files-filter-name" class="form-control" data-i18n="chatFilesPage.searchNamePlaceholder" data-i18n-attr="placeholder" placeholder="筛选文件名" oninput="chatFilesFilterNameOnInput()" onkeydown="if(event.key==='Enter') loadChatFilesPage()" />
                            </label>
                            <label>
                                <span data-i18n="chatFilesPage.groupBy">分组</span>
                                <select id="chat-files-group-by" class="form-control" onchange="chatFilesGroupByChange()">
                                    <option value="none" data-i18n="chatFilesPage.groupNone">不分组</option>
                                    <option value="date" data-i18n="chatFilesPage.groupByDate">按日期</option>
                                    <option value="conversation" data-i18n="chatFilesPage.groupByConversation">按会话</option>
                                    <option value="folder" data-i18n="chatFilesPage.groupByFolder">按文件夹</option>
                                </select>
                            </label>
                            <button class="btn-secondary" type="button" onclick="loadChatFilesPage()" data-i18n="common.search">搜索</button>
                        </div>
                        <div id="chat-files-upload-progress" class="chat-upload-progress-row chat-upload-progress-row--files" hidden role="status" aria-live="polite">
                            <div class="chat-upload-progress-track" aria-hidden="true"><div class="chat-upload-progress-fill" id="chat-files-upload-progress-fill"></div></div>
                            <span class="chat-upload-progress-label" id="chat-files-upload-progress-label"></span>
                        </div>
                        <div id="chat-files-list-wrap" class="chat-files-table-wrap">
                            <div class="loading-spinner" data-i18n="common.loading">加载中…</div>
                        </div>
                    </div>
                </div>

                <!-- 任务管理页面 -->
                <div id="page-tasks" class="page">
                    <div class="page-header">
                        <h2 data-i18n="tasks.title">任务管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-primary" onclick="showBatchImportModal()" data-i18n="tasks.newTask">新建任务</button>
                            <label class="auto-refresh-toggle">
                                <input type="checkbox" id="tasks-auto-refresh" checked onchange="toggleTasksAutoRefresh(this.checked)">
                                <span data-i18n="tasks.autoRefresh">自动刷新</span>
                            </label>
                            <button class="btn-secondary" onclick="refreshBatchQueues()" data-i18n="common.refresh">刷新</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <!-- 批量任务队列列表 -->
                        <div class="batch-queues-section" id="batch-queues-section" style="display: none;">
                            <!-- 筛选控件 -->
                            <div class="batch-queues-filters tasks-filters batch-queues-filters--compact">
                                <label>
                                    <span data-i18n="tasksPage.statusFilter">状态筛选</span>
                                    <select id="batch-queues-status-filter" onchange="filterBatchQueues()">
                                        <option value="all" data-i18n="knowledgePage.all">全部</option>
                                        <option value="pending" data-i18n="tasksPage.statusPending">待执行</option>
                                        <option value="running" data-i18n="dashboard.executing">执行中</option>
                                        <option value="paused" data-i18n="tasksPage.statusPaused">已暂停</option>
                                        <option value="completed" data-i18n="dashboard.completed">已完成</option>
                                        <option value="cancelled" data-i18n="tasksPage.statusCancelled">已取消</option>
                                    </select>
                                </label>
                                <label class="batch-queues-filters__search">
                                    <span data-i18n="tasksPage.searchQueuePlaceholder">搜索队列ID、标题或创建时间</span>
                                    <input type="text" id="batch-queues-search" data-i18n="tasksPage.searchKeywordPlaceholder" data-i18n-attr="placeholder" placeholder="输入关键字搜索..." 
                                           oninput="filterBatchQueues()">
                                </label>
                            </div>
                            <div class="batch-queues-board">
                                <div id="batch-queues-list" class="batch-queues-list"></div>
                                <div id="batch-queues-pagination" class="pagination-container"></div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- C2 管理页面容器（各子页面通过 JS 动态渲染） -->
                <div id="page-c2" class="page">
                    <div class="page-header">
                        <h2 data-i18n="c2.title">C2 管理</h2>
                    </div>
                    <div class="page-content" id="c2-content">
                        <div class="c2-layout">
                            <div id="c2-main" class="c2-main">
                                <div class="c2-welcome">
                                    <div class="c2-welcome-icon">
                                        <svg width="72" height="72" viewBox="0 0 24 24" fill="none" stroke="url(#c2-grad)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
                                            <defs><linearGradient id="c2-grad" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="#00d4ff"/><stop offset="100%" stop-color="#a855f7"/></linearGradient></defs>
                                            <path d="M4.9 19.1C1 15.2 1 8.8 4.9 4.9"></path>
                                            <path d="M7.8 16.2c-2.3-2.3-2.3-6.1 0-8.5"></path>
                                            <circle cx="12" cy="12" r="2"></circle>
                                            <path d="M16.2 7.8c2.3 2.3 2.3 6.1 0 8.5"></path>
                                            <path d="M19.1 4.9C23 8.8 23 15.2 19.1 19"></path>
                                        </svg>
                                    </div>
                                    <h3 data-i18n="c2.welcomeTitle">AI-Native C2 框架</h3>
                                    <p data-i18n="c2.welcomeDesc">以 MCP 工具为一等公民，让 LLM 可以像调用 nmap 一样调用 C2 完成"上线 → 控制 → 任务 → 横向 → 清场"全流程</p>
                                    <div class="c2-stats" id="c2-dashboard-stats">
                                        <div class="c2-stat-item">
                                            <span class="c2-stat-value" id="c2-stat-listeners">-</span>
                                            <span class="c2-stat-label" data-i18n="c2.statListeners">运行中监听器</span>
                                        </div>
                                        <div class="c2-stat-item">
                                            <span class="c2-stat-value" id="c2-stat-sessions">-</span>
                                            <span class="c2-stat-label" data-i18n="c2.statSessions">在线会话</span>
                                        </div>
                                        <div class="c2-stat-item">
                                            <span class="c2-stat-value" id="c2-stat-pending">-</span>
                                            <span class="c2-stat-label" data-i18n="c2.statPending">待审任务</span>
                                        </div>
                                    </div>
                                    <div class="c2-actions">
                                        <button class="btn-primary" onclick="switchPage('c2-listeners')" data-i18n="c2.goListeners">管理监听器</button>
                                        <button class="btn-secondary" onclick="switchPage('c2-sessions')" data-i18n="c2.goSessions">查看会话</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- C2 监听器管理页面 -->
                <div id="page-c2-listeners" class="page">
                    <div class="page-header">
                        <h2 data-i18n="c2.listeners.title">监听器管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-primary" onclick="C2.showCreateListenerModal()" data-i18n="c2.listeners.headerCreateBtn">+ 创建监听器</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <div id="c2-listener-grid" class="c2-listener-grid"></div>
                    </div>
                </div>

                <!-- C2 会话管理页面 -->
                <div id="page-c2-sessions" class="page">
                    <div class="page-header">
                        <h2 data-i18n="c2.sessions.title">会话管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="C2.loadSessions()"><span data-i18n="common.refresh">刷新</span></button>
                        </div>
                    </div>
                    <div class="page-content" style="padding:0;">
                        <div class="c2-session-layout">
                            <div id="c2-session-list" class="c2-session-sidebar"></div>
                            <div id="c2-session-main" class="c2-session-main"></div>
                        </div>
                    </div>
                </div>

                <!-- C2 任务管理页面 -->
                <div id="page-c2-tasks" class="page">
                    <div class="page-header">
                        <h2 data-i18n="c2.tasks.title">任务管理</h2>
                        <div class="page-header-actions">
                            <button type="button" class="btn-danger" id="c2-tasks-batch-delete" disabled onclick="C2.deleteSelectedTasks()"><span data-i18n="c2.tasks.batchDelete">批量删除</span></button>
                            <button type="button" class="btn-secondary" onclick="C2.loadTasks()"><span data-i18n="common.refresh">刷新</span></button>
                        </div>
                    </div>
                    <div class="page-content c2-tasks-page-wrap">
                        <div class="c2-tasks-toolbar">
                            <label class="c2-tasks-select-all-label">
                                <input type="checkbox" id="c2-tasks-select-all" onchange="C2.onTasksSelectAll(this.checked)">
                                <span data-i18n="c2.tasks.selectAll">全选本页</span>
                            </label>
                        </div>
                        <div id="c2-task-list" class="c2-task-list-container"></div>
                        <div id="c2-tasks-pagination" class="pagination-container"></div>
                    </div>
                </div>

                <!-- C2 Payload 生成页面 -->
                <div id="page-c2-payloads" class="page">
                    <div class="page-header">
                        <h2 data-i18n="c2.payloads.title">Payload 生成</h2>
                    </div>
                    <div class="page-content">
                        <div class="c2-payload-grid">
                            <div class="c2-payload-card">
                                <h3>
                                    <span class="c2-payload-icon" style="background:rgba(59,130,246,0.08);color:#3b82f6;">
                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg>
                                    </span>
                                    <span data-i18n="c2.payloads.oneliner">单行 Payload</span>
                                </h3>
                                <p class="c2-payload-desc" data-i18n="c2.payloads.onelinerDesc">快速生成可在目标机直接执行的反弹命令，支持 Bash / Python / PowerShell / Curl</p>
                                <div class="c2-form-group">
                                    <label data-i18n="c2.payloads.listener">监听器</label>
                                    <select id="c2-payload-listener" class="form-control"></select>
                                </div>
                                <div class="c2-form-group">
                                    <label data-i18n="c2.payloads.kind">类型</label>
                                    <select id="c2-payload-kind" class="form-control"></select>
                                </div>
                                <div class="c2-form-group">
                                    <label data-i18n="c2.payloads.hostOptional">回连地址 (可选)</label>
                                    <input type="text" id="c2-payload-host" class="form-control" data-i18n="c2.payloads.placeholderListenerHost" data-i18n-attr="placeholder" placeholder="留空则使用监听器地址">
                                </div>
                                <button type="button" id="c2-generate-oneliner-btn" class="btn-primary" onclick="C2.generateOneliner()" style="width:100%;" data-i18n="c2.payloads.generateOnelinerBtn">生成 Oneliner</button>
                                <pre id="c2-oneliner-output" class="c2-oneliner-output" style="display:none;" onclick="C2.copyOneliner()" data-i18n="c2.payloads.clickToCopyTitle" data-i18n-attr="title" data-i18n-skip-text="true" title="点击复制"></pre>
                            </div>
                            <div class="c2-payload-card">
                                <h3>
                                    <span class="c2-payload-icon" style="background:rgba(16,185,129,0.08);color:#10b981;">
                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect><rect x="9" y="9" width="6" height="6"></rect><line x1="9" y1="1" x2="9" y2="4"></line><line x1="15" y1="1" x2="15" y2="4"></line><line x1="9" y1="20" x2="9" y2="23"></line><line x1="15" y1="20" x2="15" y2="23"></line><line x1="20" y1="9" x2="23" y2="9"></line><line x1="20" y1="14" x2="23" y2="14"></line><line x1="1" y1="9" x2="4" y2="9"></line><line x1="1" y1="14" x2="4" y2="14"></line></svg>
                                    </span>
                                    <span data-i18n="c2.payloads.build">编译 Beacon 二进制</span>
                                </h3>
                                <p class="c2-payload-desc" data-i18n="c2.payloads.buildDesc">交叉编译支持多平台的完整 Beacon 可执行文件，支持 Linux / Windows / macOS</p>
                                <div class="c2-form-group">
                                    <label data-i18n="c2.payloads.listener">监听器</label>
                                    <select id="c2-build-listener" class="form-control"></select>
                                    <p id="c2-build-loopback-hint" class="form-hint" style="display:none;margin-top:8px;color:#b45309;"></p>
                                </div>
                                <div class="c2-form-group">
                                    <label data-i18n="c2.payloads.hostOptional">回连地址（可选）</label>
                                    <input type="text" id="c2-build-host" class="form-control" data-i18n="c2.payloads.placeholderListenerHost" data-i18n-attr="placeholder" placeholder="留空则使用监听器地址">
                                </div>
                                <div class="c2-form-row">
                                    <div class="c2-form-group">
                                        <label data-i18n="c2.payloads.os">目标系统</label>
                                        <select id="c2-build-os" class="form-control">
                                            <option value="linux" data-i18n="c2.payloads.linux">Linux</option>
                                            <option value="windows" data-i18n="c2.payloads.windows">Windows</option>
                                            <option value="darwin" data-i18n="c2.payloads.darwin">macOS</option>
                                        </select>
                                    </div>
                                    <div class="c2-form-group">
                                        <label data-i18n="c2.payloads.arch">目标架构</label>
                                        <select id="c2-build-arch" class="form-control">
                                            <option value="amd64" data-i18n="c2.payloads.amd64">AMD64</option>
                                            <option value="arm64" data-i18n="c2.payloads.arm64">ARM64</option>
                                            <option value="386" data-i18n="c2.payloads.386">386</option>
                                        </select>
                                    </div>
                                </div>
                                <button id="c2-build-btn" type="button" class="btn-primary" onclick="C2.buildBeacon()" style="width:100%;" data-i18n="c2.payloads.buildBeaconBtn">构建 Beacon</button>
                                <div id="c2-build-result"></div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- C2 事件审计页面 -->
                <div id="page-c2-events" class="page">
                    <div class="page-header">
                        <h2 data-i18n="c2.events.title">事件审计</h2>
                        <div class="page-header-actions">
                            <button type="button" class="btn-danger" id="c2-events-batch-delete" disabled onclick="C2.deleteSelectedEvents()"><span data-i18n="c2.events.batchDelete">批量删除</span></button>
                            <button type="button" class="btn-secondary" onclick="C2.loadEvents()"><span data-i18n="common.refresh">刷新</span></button>
                        </div>
                    </div>
                    <div class="page-content c2-events-page-wrap">
                        <div class="c2-events-toolbar">
                            <label class="c2-events-select-all-label">
                                <input type="checkbox" id="c2-events-select-all" onchange="C2.onEventsSelectAll(this.checked)">
                                <span data-i18n="c2.events.selectAll">全选本页</span>
                            </label>
                        </div>
                        <div id="c2-event-list" class="c2-event-list"></div>
                        <div id="c2-events-pagination" class="pagination-container"></div>
                    </div>
                </div>

                <!-- C2 Profile 管理页面 -->
                <div id="page-c2-profiles" class="page">
                    <div class="page-header">
                        <h2 data-i18n="c2.profiles.title">流量伪装</h2>
                        <div class="page-header-actions">
                            <button class="btn-primary" onclick="C2.showCreateProfileModal()" data-i18n="c2.profiles.createBtn">+ 创建 Profile</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <div id="c2-profile-list" class="c2-profile-list"></div>
                    </div>
                </div>

                <!-- C2 模态框 -->
                <div id="c2-modal" class="c2-modal-overlay" style="display:none;" onclick="if(event.target===this)C2.closeModal()">
                    <div class="c2-modal" onclick="event.stopPropagation()">
                        <div id="c2-modal-content"></div>
                    </div>
                </div>

                <!-- 角色管理页面 -->
                <div id="page-roles-management" class="page">
                    <div class="page-header">
                        <h2 data-i18n="roles.title">角色管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="refreshRoles()" data-i18n="common.refresh">刷新</button>
                            <button class="btn-primary" onclick="showAddRoleModal()" data-i18n="roles.createRole">创建角色</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <div class="roles-controls">
                            <div class="roles-search-box">
                                <input type="text" id="roles-search" data-i18n="roles.searchPlaceholder" data-i18n-attr="placeholder" placeholder="搜索角色..." oninput="handleRolesSearchInput()" onkeydown="if(event.key==='Enter') searchRoles()" />
                                <button class="roles-search-clear" id="roles-search-clear" onclick="clearRolesSearch()" style="display: none;" data-i18n="common.clearSearch" data-i18n-attr="title" title="清除搜索">
                                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
                                        <path d="M15 9l-6 6M9 9l6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                    </svg>
                                </button>
                            </div>
                        </div>
                        <div id="roles-list" class="roles-grid">
                            <div class="loading-spinner" data-i18n="knowledgePage.loading">加载中...</div>
                        </div>
                    </div>
                </div>

                <!-- Skills状态监控页面 -->
                <div id="page-skills-monitor" class="page">
                    <div class="page-header">
                        <h2 data-i18n="skills.monitorTitle">Skills状态监控</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="refreshSkillsMonitor()" data-i18n="common.refresh">刷新</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <div class="monitor-sections">
                            <section class="monitor-section monitor-overview">
                                <div class="section-header">
                                    <h3 data-i18n="skills.callStats">调用统计</h3>
                                </div>
                                <div id="skills-stats" class="monitor-stats-grid">
                                    <div class="monitor-empty" data-i18n="skillsPage.loading">加载中...</div>
                                </div>
                            </section>
                            <section class="monitor-section monitor-executions">
                                <div class="section-header">
                                    <h3 data-i18n="skillsPage.skillsCallStats">Skills调用统计</h3>
                                    <div class="section-actions">
                                        <button class="btn-secondary btn-small" onclick="clearSkillsStats()" data-i18n="skillsPage.clearStatsTitle" data-i18n-attr="title" data-i18n-skip-text="true" title="清空所有统计数据"><span data-i18n="skillsPage.clearStats">清空统计</span></button>
                                    </div>
                                </div>
                                <div id="skills-monitor-list" class="monitor-table-container">
                                    <div class="monitor-empty" data-i18n="skillsPage.loading">加载中...</div>
                                </div>
                            </section>
                        </div>
                    </div>
                </div>

                <!-- Skills管理页面 -->
                <div id="page-skills-management" class="page">
                    <div class="page-header">
                        <h2 data-i18n="skills.title">Skills管理</h2>
                        <div class="page-header-actions">
                            <button class="btn-secondary" onclick="refreshSkills()" data-i18n="common.refresh">刷新</button>
                            <button class="btn-primary" onclick="showAddSkillModal()" data-i18n="skills.createSkill">创建Skill</button>
                        </div>
                    </div>
                    <div class="page-content page-content-with-pagination">
                        <div class="skills-controls">
                            <div class="skills-search-box">
                                <input type="text" id="skills-search" data-i18n="skillsPage.searchPlaceholder" data-i18n-attr="placeholder" placeholder="搜索Skills..." oninput="handleSkillsSearchInput()" onkeydown="if(event.key==='Enter') searchSkills()" />
                                <button class="skills-search-clear" id="skills-search-clear" onclick="clearSkillsSearch()" style="display: none;" data-i18n="common.clearSearch" data-i18n-attr="title" title="清除搜索">
                                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
                                        <path d="M15 9l-6 6M9 9l6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                    </svg>
                                </button>
                            </div>
                        </div>
                        <div id="skills-list" class="skills-grid">
                            <div class="loading-spinner" data-i18n="skillsPage.loading">加载中...</div>
                        </div>
                        <div id="skills-pagination" class="pagination-container pagination-fixed"></div>
                    </div>
                </div>

                <!-- 多代理子 Agent（Markdown）管理 -->
                <div id="page-agents-management" class="page">
                    <div class="page-header">
                        <h2 data-i18n="agentsPage.title">Agent 管理</h2>
                        <div class="page-header-actions">
                            <button type="button" class="btn-secondary" onclick="loadMarkdownAgents()" data-i18n="common.refresh">刷新</button>
                            <button type="button" class="btn-primary" onclick="showAddMarkdownAgentModal()" data-i18n="agentsPage.create">新建 Agent</button>
                        </div>
                    </div>
                    <div class="page-content">
                        <p class="agents-page-hint" data-i18n="agentsPage.hint">子 Agent 仅在 agents 目录下 .md 维护。</p>
                        <div id="agents-md-dir" class="agents-dir-label"></div>
                        <div id="agents-md-list" class="skills-grid">
                            <div class="loading-spinner" data-i18n="agentsPage.loading">加载中...</div>
                        </div>
                    </div>
                </div>

                <!-- Agent Markdown 编辑弹窗 -->
                <div id="agent-md-modal" class="modal" style="display: none;">
                    <div class="modal-content" style="max-width: 720px; max-height: 92vh;">
                        <div class="modal-header">
                            <h2 id="agent-md-modal-title" data-i18n="agentsPage.editTitle">编辑 Agent</h2>
                            <span class="modal-close" onclick="closeMarkdownAgentModal()">&times;</span>
                        </div>
                        <div class="modal-body" style="overflow-y: auto; max-height: calc(92vh - 130px);">
                            <input type="hidden" id="agent-md-filename-current" value="">
                            <div class="form-group" id="agent-md-filename-row">
                                <label data-i18n="agentsPage.filename">文件名（.md）</label>
                                <input type="text" id="agent-md-filename" data-i18n="agentsPage.filenamePlaceholder" data-i18n-attr="placeholder" placeholder="例如 code-reviewer.md" autocomplete="off" />
                            </div>
                            <div class="form-group">
                                <label data-i18n="agentsPage.fieldRole">类型</label>
                                <select id="agent-md-role" class="form-select">
                                    <option value="sub" data-i18n="agentsPage.roleSub">子代理</option>
                                    <option value="orchestrator" data-i18n="agentsPage.roleOrchestrator">主代理（Deep 协调者）</option>
                                </select>
                                <p class="form-hint muted" data-i18n="agentsPage.roleHint">主代理也可使用固定文件名 orchestrator.md；全目录仅允许一个主代理。</p>
                            </div>
                            <div class="form-group">
                                <label data-i18n="agentsPage.fieldId">Agent ID（留空则从名称生成）</label>
                                <input type="text" id="agent-md-id" placeholder="code-reviewer" autocomplete="off" />
                            </div>
                            <div class="form-group">
                                <label data-i18n="agentsPage.fieldName">显示名称</label>
                                <input type="text" id="agent-md-name" data-i18n="agentsPage.namePlaceholder" data-i18n-attr="placeholder" placeholder="Code Reviewer" autocomplete="off" />
                            </div>
                            <div class="form-group">
                                <label data-i18n="agentsPage.fieldDesc">描述</label>
                                <textarea id="agent-md-description" rows="2" data-i18n="agentsPage.descPlaceholder" data-i18n-attr="placeholder" placeholder="何时调用该子代理"></textarea>
                            </div>
                            <div class="form-group">
                                <label data-i18n="agentsPage.fieldTools">可用工具（逗号分隔，与角色工具 key 一致）</label>
                                <input type="text" id="agent-md-tools" placeholder="tool_a, tool_b" autocomplete="off" />
                            </div>
                            <div class="form-group">
                                <label data-i18n="agentsPage.fieldBindRole">绑定角色（可选）</label>
                                <input type="text" id="agent-md-bind-role" placeholder="" autocomplete="off" />
                            </div>
                            <div class="form-group">
                                <label data-i18n="agentsPage.fieldMaxIter">子代理最大迭代（0=使用全局默认）</label>
                                <input type="number" id="agent-md-max-iter" min="0" value="0" />
                            </div>
                            <div class="form-group">
                                <label data-i18n="agentsPage.fieldInstruction">系统提示词（Markdown 正文）</label>
                                <textarea id="agent-md-instruction" rows="14" data-i18n="agentsPage.instructionPlaceholder" data-i18n-attr="placeholder" placeholder="You are a specialist agent..."></textarea>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn-secondary" onclick="closeMarkdownAgentModal()" data-i18n="common.cancel">取消</button>
                            <button type="button" class="btn-primary" onclick="saveMarkdownAgent()" data-i18n="common.save">保存</button>
                        </div>
                    </div>
                </div>

                <!-- 系统设置页面 -->
                <div id="page-settings" class="page">
                    <div class="page-header">
                        <h2 data-i18n="settings.title">系统设置</h2>
                    </div>
                    <div class="page-content settings-layout">
                        <!-- 左侧导航栏 -->
                        <aside class="settings-sidebar">
                            <nav class="settings-nav">
                                <div class="settings-nav-item active" data-section="basic" onclick="switchSettingsSection('basic')">
                                    <span data-i18n="settings.nav.basic">基本设置</span>
                                </div>
                                <div class="settings-nav-item" data-section="infocollect" onclick="switchSettingsSection('infocollect')">
                                    <span data-i18n="settings.nav.infocollect">信息收集</span>
                                </div>
                                <div class="settings-nav-item" data-section="knowledge" onclick="switchSettingsSection('knowledge')">
                                    <span data-i18n="settings.nav.knowledge">知识库</span>
                                </div>
                                <div class="settings-nav-item" data-section="c2" onclick="switchSettingsSection('c2')">
                                    <span data-i18n="settings.nav.c2">C2</span>
                                </div>
                                <div class="settings-nav-item" data-section="robots" onclick="switchSettingsSection('robots')">
                                    <span data-i18n="settings.nav.robots">机器人设置</span>
                                </div>
                                <div class="settings-nav-item" data-section="terminal" onclick="switchSettingsSection('terminal')">
                                    <span data-i18n="settings.nav.terminal">终端</span>
                                </div>
                                <div class="settings-nav-item" data-section="security" onclick="switchSettingsSection('security')">
                                    <span data-i18n="settings.nav.security">安全设置</span>
                                </div>
                                <div class="settings-nav-item" data-section="audit" onclick="switchSettingsSection('audit')">
                                    <span data-i18n="settings.nav.audit">日志审计</span>
                                </div>
                            </nav>
                        </aside>
                        
                        <!-- 右侧内容区域 -->
                        <div class="settings-content">
                            <!-- 基本设置 -->
                            <div id="settings-section-basic" class="settings-section-content active">
                                <div class="settings-section-header">
                                    <h3 data-i18n="settingsBasic.basicTitle">基本设置</h3>
                                </div>
                                
                                <!-- OpenAI配置 -->
                                <div class="settings-subsection">
                                    <h4 data-i18n="settingsBasic.openaiConfig">OpenAI 配置</h4>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label for="openai-provider">API 提供商</label>
                                            <select id="openai-provider" style="width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--border-color, #e2e8f0); border-radius: 6px; background: var(--card-bg, #fff); color: var(--text-color, #2d3748); font-size: 0.875rem;">
                                                <option value="openai">OpenAI / 兼容 OpenAI 协议</option>
                                                <option value="claude">Claude (Anthropic Messages API)</option>
                                            </select>
                                        </div>
                                        <div class="form-group">
                                            <label for="openai-base-url">Base URL <span style="color: red;">*</span></label>
                                            <input type="text" id="openai-base-url" data-i18n="settingsBasic.openaiBaseUrlPlaceholder" data-i18n-attr="placeholder" placeholder="https://api.openai.com/v1" required />
                                        </div>
                                        <div class="form-group">
                                            <label for="openai-api-key">API Key <span style="color: red;">*</span></label>
                                            <input type="password" id="openai-api-key" data-i18n="settingsBasic.openaiApiKeyPlaceholder" data-i18n-attr="placeholder" placeholder="输入OpenAI API Key" required />
                                        </div>
                                        <div class="form-group">
                                            <label for="openai-model"><span data-i18n="settingsBasic.model">模型</span> <span style="color: red;">*</span></label>
                                            <input type="text" id="openai-model" data-i18n="settingsBasic.modelPlaceholder" data-i18n-attr="placeholder" placeholder="gpt-4" required />
                                        </div>
                                        <div class="form-group">
                                            <label for="openai-max-total-tokens"><span data-i18n="settingsBasic.maxTotalTokens">最大上下文 Token 数</span></label>
                                            <input type="number" id="openai-max-total-tokens" data-i18n="settingsBasic.maxTotalTokensPlaceholder" data-i18n-attr="placeholder" placeholder="120000" min="1000" step="1000" />
                                            <small style="color: var(--text-muted, #718096); font-size: 0.75rem;" data-i18n="settingsBasic.maxTotalTokensHint">内存压缩和攻击链构建共用此配置，默认 120000</small>
                                        </div>
                                        <div class="form-group">
                                            <label data-i18n="settingsBasic.openaiReasoningTitle">模型推理（Eino）</label>
                                            <small class="form-hint" data-i18n="settingsBasic.openaiReasoningHint">仅影响 Eino 单代理与多代理；对话页可覆盖（见下方「允许对话覆盖」）。</small>
                                            <div style="display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; align-items: center;">
                                                <label for="openai-reasoning-mode" style="font-size: 0.8125rem;" data-i18n="chat.reasoningModeLabel">模式</label>
                                                <select id="openai-reasoning-mode" style="min-width: 120px; padding: 0.35rem 0.5rem; border-radius: 6px; border: 1px solid var(--border-color, #e2e8f0);">
                                                    <option value="auto" data-i18n="chat.reasoningModeAuto">自动</option>
                                                    <option value="on" data-i18n="chat.reasoningModeOn">开启</option>
                                                    <option value="off" data-i18n="chat.reasoningModeOff">关闭</option>
                                                </select>
                                                <label for="openai-reasoning-effort" style="font-size: 0.8125rem;" data-i18n="chat.reasoningEffortLabel">强度</label>
                                                <select id="openai-reasoning-effort" style="min-width: 100px; padding: 0.35rem 0.5rem; border-radius: 6px; border: 1px solid var(--border-color, #e2e8f0);">
                                                    <option value="" data-i18n="chat.reasoningEffortUnset">不指定</option>
                                                    <option value="low">low</option>
                                                    <option value="medium">medium</option>
                                                    <option value="high">high</option>
                                                    <option value="xhigh">xhigh</option>
                                                    <option value="max">max</option>
                                                </select>
                                                <label for="openai-reasoning-profile" style="font-size: 0.8125rem;" data-i18n="settingsBasic.openaiReasoningProfile">线路</label>
                                                <select id="openai-reasoning-profile" style="min-width: 140px; padding: 0.35rem 0.5rem; border-radius: 6px; border: 1px solid var(--border-color, #e2e8f0);">
                                                    <option value="auto">auto</option>
                                                    <option value="deepseek_compat">deepseek_compat</option>
                                                    <option value="openai_compat">openai_compat</option>
                                                    <option value="output_config_effort">output_config_effort</option>
                                                </select>
                                            </div>
                                            <label class="checkbox-label" style="margin-top: 8px;">
                                                <input type="checkbox" id="openai-reasoning-allow-client" class="modern-checkbox" checked />
                                                <span class="checkbox-custom"></span>
                                                <span class="checkbox-text" data-i18n="settingsBasic.openaiReasoningAllowClient">允许对话页覆盖推理选项</span>
                                            </label>
                                        </div>
                                        <div style="display: flex; align-items: center; gap: 8px; margin-top: 2px;">
                                            <a href="javascript:void(0)" id="test-openai-btn" onclick="testOpenAIConnection()" style="font-size: 0.8125rem; color: var(--accent-color, #3182ce); text-decoration: none; cursor: pointer; user-select: none;" data-i18n="settingsBasic.testConnection">测试连接</a>
                                            <span id="test-openai-result" style="font-size: 0.8125rem;"></span>
                                        </div>
                                    </div>
                                </div>

                                <!-- Agent配置 -->
                                <div class="settings-subsection">
                                    <h4 data-i18n="settingsBasic.agentConfig">Agent 配置</h4>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label for="agent-max-iterations" data-i18n="settingsBasic.maxIterations">最大迭代次数</label>
                                            <input type="number" id="agent-max-iterations" min="1" max="100" data-i18n="settingsBasic.iterationsPlaceholder" data-i18n-attr="placeholder" placeholder="30" />
                                        </div>
                                        <div class="form-group">
                                            <label class="checkbox-label">
                                                <input type="checkbox" id="multi-agent-enabled" class="modern-checkbox" />
                                                <span class="checkbox-custom"></span>
                                                <span class="checkbox-text" data-i18n="settingsBasic.enableMultiAgent">启用 Eino 多代理</span>
                                            </label>
                                            <small class="form-hint" data-i18n="settingsBasic.enableMultiAgentHint">开启后对话页可选「多代理」模式；子代理在 config.yaml 的 multi_agent.sub_agents 或 agents 目录中配置。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="multi-agent-pe-loop" data-i18n="settingsBasic.multiAgentPeLoop">plan_execute 外层循环上限</label>
                                            <input type="number" id="multi-agent-pe-loop" min="0" step="1" value="0" data-i18n="settingsBasic.multiAgentPeLoopPlaceholder" data-i18n-attr="placeholder" placeholder="0 表示 Eino 默认 10" />
                                            <small class="form-hint" data-i18n="settingsBasic.multiAgentPeLoopHint">仅 orchestration=plan_execute 时有效；execute 与 replan 之间的最大轮次。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="multi-agent-robot-mode" data-i18n="settingsBasic.multiAgentRobotMode">机器人默认对话模式</label>
                                            <select id="multi-agent-robot-mode" class="form-select">
                                                <option value="react" data-i18n="chat.agentModeReactNative">原生 ReAct</option>
                                                <option value="eino_single" data-i18n="chat.agentModeEinoSingle">Eino 单代理（ADK）</option>
                                                <option value="deep" data-i18n="chat.agentModeDeep">Deep（DeepAgent）</option>
                                                <option value="plan_execute" data-i18n="chat.agentModePlanExecuteLabel">Plan-Execute</option>
                                                <option value="supervisor" data-i18n="chat.agentModeSupervisorLabel">Supervisor</option>
                                            </select>
                                            <small class="form-hint" data-i18n="settingsBasic.multiAgentRobotModeHint">企业微信 / 钉钉 / 飞书机器人每条消息使用的执行模式；Deep / Plan-Execute / Supervisor 需启用多代理。</small>
                                        </div>
                                    </div>
                                </div>

                                <div class="settings-actions">
                                    <button class="btn-primary" onclick="applySettings()" data-i18n="settings.apply.button">应用配置</button>
                                </div>
                            </div>

                            <!-- 信息收集设置 -->
                            <div id="settings-section-infocollect" class="settings-section-content">
                                <div class="settings-section-header">
                                    <h3 data-i18n="settings.infocollect.title">信息收集</h3>
                                </div>

                                <!-- FOFA配置 -->
                                <div class="settings-subsection">
                                    <h4 data-i18n="settingsBasic.fofaConfig">FOFA 配置</h4>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label for="fofa-base-url">Base URL</label>
                                            <input type="text" id="fofa-base-url" data-i18n="settingsBasic.fofaBaseUrlPlaceholder" data-i18n-attr="placeholder" placeholder="https://fofa.info/api/v1/search/all（可选）" />
                                            <small class="form-hint" data-i18n="settingsBasic.fofaBaseUrlHint">留空则使用默认地址。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="fofa-email" data-i18n="settingsBasic.email">Email</label>
                                            <input type="text" id="fofa-email" data-i18n="settingsBasic.fofaEmailPlaceholder" data-i18n-attr="placeholder" placeholder="输入 FOFA 账号邮箱" autocomplete="off" />
                                        </div>
                                        <div class="form-group">
                                            <label for="fofa-api-key">API Key</label>
                                            <input type="password" id="fofa-api-key" data-i18n="settingsBasic.fofaApiKeyPlaceholder" data-i18n-attr="placeholder" placeholder="输入 FOFA API Key" autocomplete="off" />
                                            <small class="form-hint" data-i18n="settingsBasic.fofaApiKeyHint">仅保存在服务器配置中（`config.yaml`）。</small>
                                        </div>
                                    </div>
                                </div>

                                <div class="settings-actions">
                                    <button type="button" class="btn-primary" onclick="applySettings()" data-i18n="settings.apply.button">应用配置</button>
                                </div>
                            </div>

                            <!-- 知识库设置 -->
                            <div id="settings-section-knowledge" class="settings-section-content">
                                <div class="settings-section-header">
                                    <h3 data-i18n="settings.knowledge.title">知识库设置</h3>
                                </div>

                                <div class="settings-subsection">
                                    <h4 data-i18n="settingsBasic.knowledgeConfig">知识库配置</h4>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label class="checkbox-label">
                                                <input type="checkbox" id="knowledge-enabled" class="modern-checkbox" />
                                                <span class="checkbox-custom"></span>
                                                <span class="checkbox-text" data-i18n="settingsBasic.enableKnowledge">启用知识检索功能</span>
                                            </label>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-base-path" data-i18n="settingsBasic.knowledgeBasePath">知识库路径</label>
                                            <input type="text" id="knowledge-base-path" data-i18n="settingsBasic.knowledgeBasePathPlaceholder" data-i18n-attr="placeholder" placeholder="knowledge_base" />
                                            <small class="form-hint" data-i18n="settingsBasic.knowledgeBasePathHint">相对于配置文件所在目录的路径</small>
                                        </div>

                                        <div class="settings-subsection-header">
                                            <h5 data-i18n="settingsBasic.embeddingConfig">嵌入模型配置</h5>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-embedding-provider" data-i18n="settingsBasic.provider">提供商</label>
                                            <select id="knowledge-embedding-provider">
                                                <option value="openai">OpenAI</option>
                                            </select>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-embedding-base-url">Base URL</label>
                                            <input type="text" id="knowledge-embedding-base-url" data-i18n="settingsBasic.embeddingBaseUrlPlaceholder" data-i18n-attr="placeholder" placeholder="留空则使用OpenAI配置的base_url" />
                                            <small class="form-hint" data-i18n="settingsBasic.embeddingBaseUrlPlaceholder">留空则使用OpenAI配置的base_url</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-embedding-api-key">API Key</label>
                                            <input type="password" id="knowledge-embedding-api-key" data-i18n="settingsBasic.embeddingApiKeyPlaceholder" data-i18n-attr="placeholder" placeholder="留空则使用OpenAI配置的api_key" />
                                            <small class="form-hint" data-i18n="settingsBasic.embeddingApiKeyPlaceholder">留空则使用OpenAI配置的api_key</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-embedding-model" data-i18n="settingsBasic.modelName">模型名称</label>
                                            <input type="text" id="knowledge-embedding-model" data-i18n="settingsBasic.embeddingModelPlaceholder" data-i18n-attr="placeholder" placeholder="text-embedding-v4" />
                                        </div>

                                        <div class="settings-subsection-header">
                                            <h5 data-i18n="settingsBasic.retrievalConfig">检索配置</h5>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-retrieval-top-k" data-i18n="settingsBasic.topK">Top-K 结果数量</label>
                                            <input type="number" id="knowledge-retrieval-top-k" min="1" max="20" data-i18n="settingsBasic.topKPlaceholder" data-i18n-attr="placeholder" placeholder="5" />
                                            <small class="form-hint" data-i18n="settingsBasic.topKHint">检索返回的Top-K结果数量</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-retrieval-similarity-threshold" data-i18n="settingsBasic.similarityThreshold">相似度阈值</label>
                                            <input type="number" id="knowledge-retrieval-similarity-threshold" min="0" max="1" step="0.1" data-i18n="settingsBasic.similarityPlaceholder" data-i18n-attr="placeholder" placeholder="0.7" />
                                            <small class="form-hint" data-i18n="settingsBasic.similarityHint">相似度阈值（0-1），低于此值的结果将被过滤</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-retrieval-sub-index-filter" data-i18n="settingsBasic.subIndexFilter">子索引过滤（可选）</label>
                                            <input type="text" id="knowledge-retrieval-sub-index-filter" data-i18n="settingsBasic.subIndexFilterPlaceholder" data-i18n-attr="placeholder" placeholder="与索引 sub_indexes 标签一致，如 prod" />
                                            <small class="form-hint" data-i18n="settingsBasic.subIndexFilterHint">留空表示不过滤；非空时仅检索 sub_indexes 含该标签的向量行（未打标旧数据仍会命中）。</small>
                                        </div>

                                        <div class="settings-subsection-header">
                                            <h5 data-i18n="settingsBasic.postRetrieveHeader">检索后处理（去重 / 预算）</h5>
                                        </div>
                                        <p class="form-hint" style="margin: 0 0 12px 0;" data-i18n="settingsBasic.postRetrieveDedupeAuto">检索结果会自动按正文规范化去重（合并仅空白不同的重复片段），无需配置。</p>
                                        <div class="form-group">
                                            <label for="knowledge-post-retrieve-prefetch-top-k" data-i18n="settingsBasic.prefetchTopK">预取候选数（向量阶段）</label>
                                            <input type="number" id="knowledge-post-retrieve-prefetch-top-k" min="0" max="200" data-i18n="settingsBasic.prefetchTopKPlaceholder" data-i18n-attr="placeholder" placeholder="0" />
                                            <small class="form-hint" data-i18n="settingsBasic.prefetchTopKHint">0 表示与 Top-K 相同；大于 Top-K 时先多取候选再经去重/截断回到 Top-K（上限 200）。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-post-retrieve-max-chars" data-i18n="settingsBasic.maxContextChars">返回内容最大字符数（Unicode）</label>
                                            <input type="number" id="knowledge-post-retrieve-max-chars" min="0" max="1000000" data-i18n="settingsBasic.maxContextCharsPlaceholder" data-i18n-attr="placeholder" placeholder="0" />
                                            <small class="form-hint" data-i18n="settingsBasic.maxContextCharsHint">0 表示不限制；按检索顺序整段保留 chunk，超出则丢弃后续。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-post-retrieve-max-tokens" data-i18n="settingsBasic.maxContextTokens">返回内容最大 Token 数</label>
                                            <input type="number" id="knowledge-post-retrieve-max-tokens" min="0" max="1000000" data-i18n="settingsBasic.maxContextTokensPlaceholder" data-i18n-attr="placeholder" placeholder="0" />
                                            <small class="form-hint" data-i18n="settingsBasic.maxContextTokensHint">0 表示不限制；tiktoken 估算（与嵌入模型名一致，失败则用 cl100k_base）。</small>
                                        </div>

                                        <div class="settings-subsection-header">
                                            <h5 data-i18n="settingsBasic.indexConfig">索引配置</h5>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-chunk-strategy" data-i18n="settingsBasic.chunkStrategy">分块策略</label>
                                            <select id="knowledge-indexing-chunk-strategy">
                                                <option value="markdown_then_recursive" data-i18n="settingsBasic.chunkStrategyMarkdownRecursive">Markdown 标题切分后递归（推荐）</option>
                                                <option value="recursive" data-i18n="settingsBasic.chunkStrategyRecursive">仅递归切分</option>
                                            </select>
                                            <small class="form-hint" data-i18n="settingsBasic.chunkStrategyHint">与 Eino 官方索引链一致：技术文档建议 Markdown 标题 + 递归；纯文本可仅用递归。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-request-timeout" data-i18n="settingsBasic.requestTimeoutSeconds">嵌入 HTTP 超时（秒）</label>
                                            <input type="number" id="knowledge-indexing-request-timeout" min="0" max="600" data-i18n="settingsBasic.requestTimeoutPlaceholder" data-i18n-attr="placeholder" placeholder="120" />
                                            <small class="form-hint" data-i18n="settingsBasic.requestTimeoutHint">0 表示使用默认 120 秒；与 OpenAI 嵌入客户端一致。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-batch-size" data-i18n="settingsBasic.batchSize">嵌入批大小</label>
                                            <input type="number" id="knowledge-indexing-batch-size" min="1" max="256" data-i18n="settingsBasic.batchSizePlaceholder" data-i18n-attr="placeholder" placeholder="64" />
                                            <small class="form-hint" data-i18n="settingsBasic.batchSizeHint">单次请求嵌入的文本条数上限（SQLite 索引写入分批）。</small>
                                        </div>
                                        <div class="form-group">
                                            <label class="checkbox-label">
                                                <input type="checkbox" id="knowledge-indexing-prefer-source-file" />
                                                <span data-i18n="settingsBasic.preferSourceFile">索引时优先从磁盘源文件读取（Eino FileLoader）</span>
                                            </label>
                                            <small class="form-hint" data-i18n="settingsBasic.preferSourceFileHint">开启后以 file_path 为准；读取失败时回退数据库中的 content。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-sub-indexes" data-i18n="settingsBasic.subIndexes">Eino 子索引（逗号分隔）</label>
                                            <input type="text" id="knowledge-indexing-sub-indexes" data-i18n="settingsBasic.subIndexesPlaceholder" data-i18n-attr="placeholder" placeholder="例如: prod, knowledge" />
                                            <small class="form-hint" data-i18n="settingsBasic.subIndexesHint">传入 indexer.WithSubIndexes，写入向量行的 sub_indexes 字段（逻辑分区标记）。</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-chunk-size" data-i18n="settingsBasic.chunkSize">分块大小（Chunk Size）</label>
                                            <input type="number" id="knowledge-indexing-chunk-size" min="128" max="4096" data-i18n="settingsBasic.chunkSizePlaceholder" data-i18n-attr="placeholder" placeholder="512" />
                                            <small class="form-hint" data-i18n="settingsBasic.chunkSizeHint">每个块的最大 token 数（默认 512），长文本会被分割成多个块</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-chunk-overlap" data-i18n="settingsBasic.chunkOverlap">分块重叠（Chunk Overlap）</label>
                                            <input type="number" id="knowledge-indexing-chunk-overlap" min="0" max="512" data-i18n="settingsBasic.chunkOverlapPlaceholder" data-i18n-attr="placeholder" placeholder="50" />
                                            <small class="form-hint" data-i18n="settingsBasic.chunkOverlapHint">块之间的重叠 token 数（默认 50），保持上下文连贯性</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-max-chunks-per-item" data-i18n="settingsBasic.maxChunksPerItem">单个知识项最大块数</label>
                                            <input type="number" id="knowledge-indexing-max-chunks-per-item" min="0" max="1000" data-i18n="settingsBasic.maxChunksPlaceholder" data-i18n-attr="placeholder" placeholder="0" />
                                            <small class="form-hint" data-i18n="settingsBasic.maxChunksHint">单个知识项的最大块数量（0 表示不限制），防止单个文件消耗过多 API 配额</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-max-rpm" data-i18n="settingsBasic.maxRpm">每分钟最大请求数（Max RPM）</label>
                                            <input type="number" id="knowledge-indexing-max-rpm" min="0" max="1000" data-i18n="settingsBasic.maxRpmPlaceholder" data-i18n-attr="placeholder" placeholder="0" />
                                            <small class="form-hint" data-i18n="settingsBasic.maxRpmHint">每分钟最大请求数（默认 0 表示不限制），如 OpenAI 默认 200 RPM</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-rate-limit-delay-ms" data-i18n="settingsBasic.rateLimitDelay">请求间隔延迟（毫秒）</label>
                                            <input type="number" id="knowledge-indexing-rate-limit-delay-ms" min="0" max="10000" data-i18n="settingsBasic.rateLimitPlaceholder" data-i18n-attr="placeholder" placeholder="300" />
                                            <small class="form-hint" data-i18n="settingsBasic.rateLimitHint">请求间隔毫秒数（默认 300），用于避免 API 速率限制，设为 0 不限制</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-max-retries" data-i18n="settingsBasic.maxRetries">最大重试次数</label>
                                            <input type="number" id="knowledge-indexing-max-retries" min="0" max="10" data-i18n="settingsBasic.maxRetriesPlaceholder" data-i18n-attr="placeholder" placeholder="3" />
                                            <small class="form-hint" data-i18n="settingsBasic.maxRetriesHint">最大重试次数（默认 3），遇到速率限制或服务器错误时自动重试</small>
                                        </div>
                                        <div class="form-group">
                                            <label for="knowledge-indexing-retry-delay-ms" data-i18n="settingsBasic.retryDelay">重试间隔（毫秒）</label>
                                            <input type="number" id="knowledge-indexing-retry-delay-ms" min="0" max="10000" data-i18n="settingsBasic.retryDelayPlaceholder" data-i18n-attr="placeholder" placeholder="1000" />
                                            <small class="form-hint" data-i18n="settingsBasic.retryDelayHint">重试间隔毫秒数（默认 1000），每次重试会递增延迟</small>
                                        </div>
                                    </div>
                                </div>

                                <div class="settings-actions">
                                    <button class="btn-primary" onclick="applySettings()" data-i18n="settings.apply.button">应用配置</button>
                                </div>
                            </div>

                            <!-- C2 总开关 -->
                            <div id="settings-section-c2" class="settings-section-content">
                                <div class="settings-section-header">
                                    <h3 data-i18n="settings.c2.title">C2 设置</h3>
                                </div>
                                <div class="settings-subsection">
                                    <h4 data-i18n="settings.c2.sectionTitle">内置 C2</h4>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label class="checkbox-label">
                                                <input type="checkbox" id="c2-enabled" class="modern-checkbox" />
                                                <span class="checkbox-custom"></span>
                                                <span class="checkbox-text" data-i18n="settings.c2.enableLabel">启用内置 C2（监听器、会话、Payload、MCP 工具等）</span>
                                            </label>
                                            <small class="form-hint" data-i18n="settings.c2.enableHint">关闭后不再启动监听器、不注册 C2 相关 MCP 工具，侧栏 C2 入口将隐藏；仅本机使用对话与知识库时可关闭以节省资源。</small>
                                        </div>
                                    </div>
                                </div>
                                <div class="settings-actions">
                                    <button class="btn-primary" onclick="applySettings()" data-i18n="settings.apply.button">应用配置</button>
                                </div>
                            </div>

                            <!-- 机器人设置 -->
                            <div id="settings-section-robots" class="settings-section-content">
                                <div class="settings-section-header">
                                    <h3 data-i18n="settings.robots.title">机器人设置</h3>
                                    <p class="settings-description" data-i18n="settings.robots.description">配置企业微信、钉钉、飞书等机器人，在手机端直接与 CyberStrikeAI 对话，无需在服务器上打开网页。</p>
                                </div>

                                <!-- 微信 / iLink -->
                                <div class="settings-subsection robot-wechat-card" id="robot-wechat-subsection">
                                    <div class="robot-wechat-header">
                                        <div class="robot-wechat-header-text">
                                            <h4 data-i18n="settings.robots.wechat.title">微信 / iLink</h4>
                                            <p class="robot-wechat-subtitle" data-i18n="settings.robots.wechat.subtitle">扫码绑定个人微信，在手机端直接与 CyberStrikeAI 对话</p>
                                        </div>
                                        <span id="robot-wechat-status-badge" class="robot-wechat-badge robot-wechat-badge--idle" data-i18n="settings.robots.wechat.statusIdle">未绑定</span>
                                    </div>
                                    <div class="settings-form robot-wechat-form">
                                        <div class="robot-wechat-toolbar">
                                            <label class="checkbox-label">
                                                <input type="checkbox" id="robot-wechat-enabled" class="modern-checkbox" />
                                                <span class="checkbox-custom"></span>
                                                <span class="checkbox-text" data-i18n="settings.robots.wechat.enabled">启用微信机器人</span>
                                            </label>
                                        </div>
                                        <div class="robot-wechat-action-row">
                                            <button type="button" class="btn-primary" id="robot-wechat-bind-btn" onclick="startWechatRobotBind()" data-i18n="settings.robots.wechat.bindButton">生成二维码并绑定</button>
                                            <p class="robot-wechat-hint" id="robot-wechat-bind-hint" data-i18n="settings.robots.wechat.bindHint">用微信扫码确认后会自动保存并启用。</p>
                                        </div>
                                        <div id="robot-wechat-qr-wrap" class="robot-wechat-panel" hidden>
                                            <div id="robot-wechat-bound-panel" class="robot-wechat-bound-panel" hidden>
                                                <div class="robot-wechat-bound-icon" aria-hidden="true">
                                                    <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
                                                </div>
                                                <p class="robot-wechat-bound-msg" data-i18n="settings.robots.wechat.boundSuccess">绑定成功，微信机器人已启用</p>
                                                <p id="robot-wechat-bound-id" class="robot-wechat-bound-id" hidden></p>
                                            </div>
                                            <div id="robot-wechat-scan-panel" class="robot-wechat-scan-panel" hidden>
                                            <div id="robot-wechat-qr-loading" class="robot-wechat-qr-loading" hidden data-i18n="settings.robots.wechat.qrLoading">正在生成二维码…</div>
                                            <img id="robot-wechat-qr-img" class="robot-wechat-qr-img" alt="" width="220" height="220" hidden />
                                            <p class="robot-wechat-qr-fallback">
                                                <a id="robot-wechat-qr-link" href="#" target="_blank" rel="noopener noreferrer" hidden data-i18n="settings.robots.wechat.openLink">无法显示二维码？点击用手机微信打开链接</a>
                                            </p>
                                            <p id="robot-wechat-qr-status" class="robot-wechat-qr-status"></p>
                                            <div id="robot-wechat-verify-wrap" class="robot-wechat-verify-wrap" hidden>
                                                <label for="robot-wechat-verify-code" data-i18n="settings.robots.wechat.verifyCodeLabel">手机显示的数字（仅部分账号需要）</label>
                                                <div class="robot-wechat-verify-row">
                                                    <input type="text" id="robot-wechat-verify-code" inputmode="numeric" autocomplete="one-time-code" maxlength="8" placeholder="000000" />
                                                    <button type="button" class="btn-primary btn-sm" onclick="submitWechatVerifyCode()" data-i18n="settings.robots.wechat.verifyCodeSubmit">提交</button>
                                                </div>
                                            </div>
                                            </div>
                                        </div>
                                        <details class="settings-collapsible robot-wechat-advanced" id="robot-wechat-advanced">
                                            <summary data-i18n="settings.robots.wechat.advanced">高级设置</summary>
                                            <div class="form-group">
                                                <label for="robot-wechat-base-url" data-i18n="settings.robots.wechat.baseUrl">API Base URL</label>
                                                <input type="text" id="robot-wechat-base-url" placeholder="https://ilinkai.weixin.qq.com" autocomplete="off" />
                                            </div>
                                            <div class="form-group">
                                                <label for="robot-wechat-bot-type" data-i18n="settings.robots.wechat.botType">Bot Type</label>
                                                <input type="text" id="robot-wechat-bot-type" placeholder="3" autocomplete="off" />
                                            </div>
                                            <div class="form-group">
                                                <label for="robot-wechat-bot-agent" data-i18n="settings.robots.wechat.botAgent">Bot Agent</label>
                                                <input type="text" id="robot-wechat-bot-agent" placeholder="CyberStrikeAI/1.0" autocomplete="off" />
                                            </div>
                                            <div class="form-group">
                                                <label for="robot-wechat-ilink-bot-id" data-i18n="settings.robots.wechat.ilinkBotId">iLink Bot ID（绑定后自动填充）</label>
                                                <input type="text" id="robot-wechat-ilink-bot-id" readonly autocomplete="off" />
                                            </div>
                                        </details>
                                    </div>
                                </div>

                                <!-- 企业微信 -->
                                <div class="settings-subsection">
                                    <h4 data-i18n="settings.robots.wecom.title">企业微信</h4>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label class="checkbox-label">
                                                <input type="checkbox" id="robot-wecom-enabled" class="modern-checkbox" />
                                                <span class="checkbox-custom"></span>
                                                <span class="checkbox-text" data-i18n="settings.robots.wecom.enabled">启用企业微信机器人</span>
                                            </label>
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-wecom-token" data-i18n="settings.robots.wecom.token">Token</label>
                                            <input type="text" id="robot-wecom-token" data-i18n="settings.robots.wecom.tokenPlaceholder" data-i18n-attr="placeholder" placeholder="Token" autocomplete="off" />
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-wecom-encoding-aes-key" data-i18n="settings.robots.wecom.encodingAesKey">EncodingAESKey</label>
                                            <input type="text" id="robot-wecom-encoding-aes-key" data-i18n="settings.robots.wecom.encodingAesKeyPlaceholder" data-i18n-attr="placeholder" placeholder="EncodingAESKey（明文模式可留空）" autocomplete="off" />
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-wecom-corp-id" data-i18n="settings.robots.wecom.corpId">CorpID</label>
                                            <input type="text" id="robot-wecom-corp-id" data-i18n="settings.robots.wecom.corpIdPlaceholder" data-i18n-attr="placeholder" placeholder="企业 ID" autocomplete="off" />
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-wecom-secret" data-i18n="settings.robots.wecom.secret">Secret</label>
                                            <input type="password" id="robot-wecom-secret" data-i18n="settings.robots.wecom.secretPlaceholder" data-i18n-attr="placeholder" placeholder="应用 Secret" autocomplete="off" />
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-wecom-agent-id" data-i18n="settings.robots.wecom.agentId">AgentID</label>
                                            <input type="number" id="robot-wecom-agent-id" data-i18n="settings.robots.wecom.agentIdPlaceholder" data-i18n-attr="placeholder" placeholder="应用 AgentId" />
                                        </div>
                                    </div>
                                </div>

                                <!-- 钉钉 -->
                                <div class="settings-subsection">
                                    <h4 data-i18n="settings.robots.dingtalk.title">钉钉</h4>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label class="checkbox-label">
                                                <input type="checkbox" id="robot-dingtalk-enabled" class="modern-checkbox" />
                                                <span class="checkbox-custom"></span>
                                                <span class="checkbox-text" data-i18n="settings.robots.dingtalk.enabled">启用钉钉机器人</span>
                                            </label>
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-dingtalk-client-id" data-i18n="settings.robots.dingtalk.clientIdLabel">Client ID (AppKey)</label>
                                            <input type="text" id="robot-dingtalk-client-id" data-i18n="settings.robots.dingtalk.clientIdPlaceholder" data-i18n-attr="placeholder" placeholder="钉钉应用 AppKey" autocomplete="off" />
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-dingtalk-client-secret" data-i18n="settings.robots.dingtalk.clientSecretLabel">Client Secret</label>
                                            <input type="password" id="robot-dingtalk-client-secret" data-i18n="settings.robots.dingtalk.clientSecretPlaceholder" data-i18n-attr="placeholder" placeholder="钉钉应用 Secret" autocomplete="off" />
                                            <small class="form-hint" data-i18n="settings.robots.dingtalk.streamHint">需开启机器人能力并配置流式接入</small>
                                        </div>
                                    </div>
                                </div>

                                <!-- 飞书 -->
                                <div class="settings-subsection">
                                    <h4 data-i18n="settings.robots.lark.title">飞书 (Lark)</h4>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label class="checkbox-label">
                                                <input type="checkbox" id="robot-lark-enabled" class="modern-checkbox" />
                                                <span class="checkbox-custom"></span>
                                                <span class="checkbox-text" data-i18n="settings.robots.lark.enabled">启用飞书机器人</span>
                                            </label>
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-lark-app-id" data-i18n="settings.robots.lark.appIdLabel">App ID</label>
                                            <input type="text" id="robot-lark-app-id" data-i18n="settings.robots.lark.appIdPlaceholder" data-i18n-attr="placeholder" placeholder="飞书应用 App ID" autocomplete="off" />
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-lark-app-secret" data-i18n="settings.robots.lark.appSecretLabel">App Secret</label>
                                            <input type="password" id="robot-lark-app-secret" data-i18n="settings.robots.lark.appSecretPlaceholder" data-i18n-attr="placeholder" placeholder="飞书应用 App Secret" autocomplete="off" />
                                        </div>
                                        <div class="form-group">
                                            <label for="robot-lark-verify-token" data-i18n="settings.robots.lark.verifyTokenLabel">Verify Token（可选）</label>
                                            <input type="text" id="robot-lark-verify-token" data-i18n="settings.robots.lark.verifyTokenPlaceholder" data-i18n-attr="placeholder" placeholder="事件订阅 Verification Token" autocomplete="off" />
                                        </div>
                                    </div>
                                </div>

                                <div class="settings-subsection">
                                    <h4 data-i18n="settingsRobotsExtra.botCommandsTitle">机器人命令说明</h4>
                                    <p class="settings-description" data-i18n="settingsRobotsExtra.botCommandsDesc">在对话中可发送以下命令（支持中英文）：</p>

                                    <p class="robot-cmd-category" data-i18n="settingsRobotsExtra.botCmdCategoryGeneral">通用</p>
                                    <ul class="robot-cmd-list">
                                        <li><code>帮助</code> <code>help</code> — <span data-i18n="settingsRobotsExtra.botCmdHelp">显示本帮助 | Show this help</span></li>
                                        <li><code>版本</code> <code>version</code> — <span data-i18n="settingsRobotsExtra.botCmdVersion">显示当前版本号 | Show version</span></li>
                                    </ul>

                                    <p class="robot-cmd-category" data-i18n="settingsRobotsExtra.botCmdCategoryConversation">对话</p>
                                    <ul class="robot-cmd-list">
                                        <li><code>列表</code> <code>list</code> — <span data-i18n="settingsRobotsExtra.botCmdList">列出所有对话标题与 ID | List conversations</span></li>
                                        <li><code>切换 &lt;ID&gt;</code> <code>switch &lt;ID&gt;</code> — <span data-i18n="settingsRobotsExtra.botCmdSwitch">指定对话继续 | Switch to conversation</span></li>
                                        <li><code>新对话</code> <code>new</code> — <span data-i18n="settingsRobotsExtra.botCmdNew">开启新对话 | Start new conversation</span></li>
                                        <li><code>清空</code> <code>clear</code> — <span data-i18n="settingsRobotsExtra.botCmdClear">清空当前上下文 | Clear context</span></li>
                                        <li><code>当前</code> <code>current</code> — <span data-i18n="settingsRobotsExtra.botCmdCurrent">显示当前对话、角色与项目 | Show current conversation</span></li>
                                        <li><code>停止</code> <code>stop</code> — <span data-i18n="settingsRobotsExtra.botCmdStop">中断当前任务 | Stop running task</span></li>
                                        <li><code>删除 &lt;ID&gt;</code> <code>delete &lt;ID&gt;</code> — <span data-i18n="settingsRobotsExtra.botCmdDelete">删除指定对话 | Delete conversation</span></li>
                                    </ul>

                                    <p class="robot-cmd-category" data-i18n="settingsRobotsExtra.botCmdCategoryRole">角色</p>
                                    <ul class="robot-cmd-list">
                                        <li><code>角色</code> <code>roles</code> — <span data-i18n="settingsRobotsExtra.botCmdRoles">列出所有可用角色 | List roles</span></li>
                                        <li><code>角色 &lt;名&gt;</code> <code>role &lt;name&gt;</code> — <span data-i18n="settingsRobotsExtra.botCmdRole">切换当前角色 | Switch role</span></li>
                                    </ul>

                                    <p class="robot-cmd-category" data-i18n="settingsRobotsExtra.botCmdCategoryProject">项目</p>
                                    <ul class="robot-cmd-list">
                                        <li><code>项目</code> <code>projects</code> — <span data-i18n="settingsRobotsExtra.botCmdProjects">列出所有项目 | List projects</span></li>
                                        <li><code>新建项目 &lt;名称&gt;</code> <code>new project &lt;name&gt;</code> — <span data-i18n="settingsRobotsExtra.botCmdNewProject">创建项目并绑定当前对话 | Create &amp; bind project</span></li>
                                        <li><code>绑定项目 &lt;ID或名称&gt;</code> <code>bind project &lt;ID|name&gt;</code> — <span data-i18n="settingsRobotsExtra.botCmdBindProject">将当前对话绑定到项目 | Bind conversation</span></li>
                                        <li><code>解除项目</code> <code>unbind project</code> — <span data-i18n="settingsRobotsExtra.botCmdUnbindProject">解除当前对话的项目绑定 | Unbind project</span></li>
                                    </ul>

                                    <p class="settings-description robot-cmd-footer" data-i18n="settingsRobotsExtra.botCommandsFooter">除以上命令外，直接输入内容将发送给 AI 进行渗透测试/安全分析。Otherwise, send any text for AI penetration testing / security analysis.</p>
                                </div>

                                <div class="settings-actions">
                                    <button class="btn-primary" onclick="applySettings()" data-i18n="settings.apply.button">应用配置</button>
                                </div>
                            </div>

                            <!-- 终端 -->
                            <div id="settings-section-terminal" class="settings-section-content">
                                <div class="settings-section-header">
                                    <h3 data-i18n="settingsTerminal.title">终端</h3>
                                    <p class="settings-description" data-i18n="settingsTerminal.description">在服务器上执行命令，便于运维与调试。命令在服务端执行，请勿执行敏感或破坏性操作。</p>
                                </div>
                                <div class="terminal-wrapper">
                                    <div class="terminal-tabs">
                                        <div class="terminal-tab active" data-tab-id="1"><span class="terminal-tab-label" onclick="switchTerminalTab(1)">终端 1</span><button type="button" class="terminal-tab-close" onclick="removeTerminalTab(1); event.stopPropagation();" data-i18n="settingsTerminal.close" data-i18n-attr="title" title="关闭">×</button></div>
                                        <button type="button" class="terminal-tab-new" onclick="addTerminalTab()" data-i18n="settingsTerminal.newTerminal" data-i18n-attr="title" title="新终端">+</button>
                                    </div>
                                    <div class="terminal-panes">
                                        <div id="terminal-pane-1" class="terminal-pane active">
                                            <div id="terminal-container-1" class="terminal-container"></div>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <!-- 日志审计 -->
                            <div id="settings-section-audit" class="settings-section-content">
                                <div class="settings-section-header">
                                    <h3 data-i18n="settingsAudit.title">日志审计</h3>
                                    <p class="settings-description" data-i18n="settingsAudit.description">记录平台管理类操作（登录、配置、删除等），不记录对话正文、终端/WebShell 每次命令与工具调用明细。</p>
                                    <p id="audit-retention-hint" class="settings-description audit-retention-hint" hidden></p>
                                </div>
                                <div id="audit-summary-stats" class="audit-summary-stats" hidden>
                                    <div class="audit-stat-card"><span class="audit-stat-label" data-i18n="settingsAudit.statTotal">当前筛选</span><strong id="audit-stat-total">0</strong></div>
                                    <div class="audit-stat-card"><span class="audit-stat-label" data-i18n="settingsAudit.statFailures">失败</span><strong id="audit-stat-failures">0</strong></div>
                                    <div class="audit-stat-card"><span class="audit-stat-label" data-i18n="settingsAudit.statRecent7d">近 7 天</span><strong id="audit-stat-recent">0</strong></div>
                                </div>
                                <div class="audit-logs-toolbar">
                                    <div class="audit-logs-filters">
                                        <label class="audit-filter-cascade-group">
                                            <span data-i18n="settingsAudit.filterEvent">事件类型</span>
                                            <div class="audit-filter-cascade">
                                                <select id="audit-filter-category" onchange="onAuditCategoryFilterChange()" aria-label="类别">
                                                    <option value="" data-i18n="settingsAudit.filterAllCategories">全部类别</option>
                                                    <option value="auth" data-i18n="settingsAudit.cat.auth">认证</option>
                                                    <option value="config" data-i18n="settingsAudit.cat.config">配置</option>
                                                    <option value="c2" data-i18n="settingsAudit.cat.c2">C2</option>
                                                    <option value="webshell" data-i18n="settingsAudit.cat.webshell">WebShell</option>
                                                    <option value="knowledge" data-i18n="settingsAudit.cat.knowledge">知识库</option>
                                                    <option value="conversation" data-i18n="settingsAudit.cat.conversation">对话</option>
                                                    <option value="vulnerability" data-i18n="settingsAudit.cat.vulnerability">漏洞</option>
                                                    <option value="external_mcp" data-i18n="settingsAudit.cat.externalMcp">外部 MCP</option>
                                                    <option value="task" data-i18n="settingsAudit.cat.task">任务</option>
                                                    <option value="tool" data-i18n="settingsAudit.cat.tool">工具</option>
                                                    <option value="file" data-i18n="settingsAudit.cat.file">文件</option>
                                                    <option value="hitl" data-i18n="settingsAudit.cat.hitl">人机协同</option>
                                                    <option value="role" data-i18n="settingsAudit.cat.role">角色</option>
                                                    <option value="skill" data-i18n="settingsAudit.cat.skill">Skill</option>
                                                    <option value="agent" data-i18n="settingsAudit.cat.agent">子代理</option>
                                                </select>
                                                <span class="audit-filter-cascade-arrow" aria-hidden="true">→</span>
                                                <select id="audit-filter-action" disabled aria-label="操作">
                                                    <option value="" data-i18n="settingsAudit.filterAllActions">全部操作</option>
                                                </select>
                                            </div>
                                        </label>
                                        <label>
                                            <span data-i18n="settingsAudit.filterResult">结果</span>
                                            <select id="audit-filter-result">
                                                <option value="" data-i18n="settingsAudit.filterAll">全部</option>
                                                <option value="success">success</option>
                                                <option value="failure">failure</option>
                                            </select>
                                        </label>
                                        <label>
                                            <span data-i18n="settingsAudit.filterSince">开始时间</span>
                                            <input type="datetime-local" id="audit-filter-since" />
                                        </label>
                                        <label>
                                            <span data-i18n="settingsAudit.filterUntil">结束时间</span>
                                            <input type="datetime-local" id="audit-filter-until" />
                                        </label>
                                        <label>
                                            <span data-i18n="settingsAudit.filterQuery">关键词</span>
                                            <input type="text" id="audit-filter-q" data-i18n="settingsAudit.filterQueryPlaceholder" data-i18n-attr="placeholder" placeholder="消息 / 资源 ID / 操作名" />
                                        </label>
                                        <button type="button" class="btn-secondary" onclick="filterAuditLogs()" data-i18n="settingsAudit.filterBtn">筛选</button>
                                        <button type="button" class="btn-secondary" onclick="resetAuditLogFilters()" data-i18n="settingsAudit.resetBtn">重置</button>
                                    </div>
                                    <div class="audit-logs-actions">
                                        <button type="button" class="btn-secondary" onclick="refreshAuditLogs()" data-i18n="common.refresh">刷新</button>
                                        <div class="audit-export-dropdown">
                                            <button type="button" class="btn-secondary audit-export-trigger" id="audit-export-trigger" onclick="toggleAuditExportMenu(event)" aria-haspopup="true" aria-expanded="false">
                                                <span data-i18n="settingsAudit.exportBtn">导出</span>
                                                <span class="audit-export-caret" aria-hidden="true">▾</span>
                                            </button>
                                            <div id="audit-export-menu" class="audit-export-menu" role="menu" hidden>
                                                <button type="button" class="audit-export-menu-item" role="menuitem" onclick="runAuditExport('json')" data-i18n="settingsAudit.exportJson">导出 JSON</button>
                                                <button type="button" class="audit-export-menu-item" role="menuitem" onclick="runAuditExport('csv')" data-i18n="settingsAudit.exportCsv">导出 CSV</button>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div id="audit-log-list" class="audit-log-list c2-event-list"></div>
                                <div id="audit-logs-pagination" class="pagination-container audit-logs-pagination"></div>
                            </div>

                            <!-- 安全设置 -->
                            <div id="settings-section-security" class="settings-section-content">
                                <div class="settings-section-header">
                                    <h3 data-i18n="settings.nav.security">安全设置</h3>
                                </div>
                                
                                <div class="settings-subsection">
                                    <h4 data-i18n="settingsSecurity.changePasswordTitle">修改密码</h4>
                                    <p class="settings-description" data-i18n="settingsSecurity.changePasswordDesc">修改登录密码后，需要使用新密码重新登录。</p>
                                    <div class="settings-form">
                                        <div class="form-group">
                                            <label for="auth-current-password" data-i18n="settingsSecurity.currentPassword">当前密码</label>
                                            <input type="password" id="auth-current-password" data-i18n="settingsSecurity.currentPasswordPlaceholder" data-i18n-attr="placeholder" placeholder="输入当前登录密码" autocomplete="current-password" />
                                        </div>
                                        <div class="form-group">
                                            <label for="auth-new-password" data-i18n="settingsSecurity.newPassword">新密码</label>
                                            <input type="password" id="auth-new-password" data-i18n="settingsSecurity.newPasswordPlaceholder" data-i18n-attr="placeholder" placeholder="设置新密码（至少 8 位）" autocomplete="new-password" />
                                        </div>
                                        <div class="form-group">
                                            <label for="auth-confirm-password" data-i18n="settingsSecurity.confirmPassword">确认新密码</label>
                                            <input type="password" id="auth-confirm-password" data-i18n="settingsSecurity.confirmPasswordPlaceholder" data-i18n-attr="placeholder" placeholder="再次输入新密码" autocomplete="new-password" />
                                        </div>
                                        <div class="form-actions">
                                            <button class="btn-secondary" type="button" onclick="resetPasswordForm()" data-i18n="settingsSecurity.clear">清空</button>
                                            <button class="btn-primary change-password-submit" type="button" onclick="changePassword()" data-i18n="settingsSecurity.changePasswordBtn">修改密码</button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>


    <!-- MCP调用详情模态框 -->
    <div id="mcp-detail-modal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h2 data-i18n="mcpDetailModal.title">工具调用详情</h2>
                <span class="modal-close" onclick="closeMCPDetail()">&times;</span>
            </div>
            <div class="modal-body">
                <div class="detail-section detail-section-overview">
                    <div class="detail-section-header">
                        <h3 data-i18n="mcpDetailModal.execInfo">执行信息</h3>
                    </div>
                    <div class="detail-info-grid">
                        <div class="detail-item">
                            <strong data-i18n="mcpDetailModal.tool">工具</strong>
                            <span id="detail-tool-name"></span>
                        </div>
                        <div class="detail-item">
                            <strong data-i18n="mcpDetailModal.status">状态</strong>
                            <span id="detail-status" class="status-chip status-unknown"></span>
                        </div>
                        <div class="detail-item">
                            <strong data-i18n="mcpDetailModal.time">时间</strong>
                            <span id="detail-time"></span>
                        </div>
                        <div class="detail-item">
                            <strong data-i18n="mcpDetailModal.executionId">执行 ID</strong>
                            <span id="detail-execution-id" class="mono-text"></span>
                        </div>
                    </div>
                </div>
                <div class="detail-section detail-abort-section" id="detail-abort-section" style="display: none;">
                    <div class="detail-section-header">
                        <h3 data-i18n="mcpDetailModal.abortTitle">运行控制</h3>
                    </div>
                    <p class="detail-abort-hint" data-i18n="mcpDetailModal.abortHint">仅中断当前工具调用；对话与多步任务会继续。</p>
                    <button type="button" class="btn-secondary btn-monitor-abort" id="detail-abort-btn" onclick="abortMCPToolExecutionFromDetail()">终止工具</button>
                </div>
                <div class="detail-section">
                    <div class="detail-section-header">
                        <h3 data-i18n="mcpDetailModal.requestParams">请求参数</h3>
                        <button class="btn-ghost" type="button" onclick="copyDetailBlock('detail-request', this)" data-i18n="mcpDetailModal.copyJson">复制 JSON</button>
                    </div>
                    <div class="detail-code-card">
                        <pre id="detail-request" class="code-block"></pre>
                    </div>
                </div>
                <div class="detail-section">
                    <div class="detail-section-header">
                        <h3 data-i18n="mcpDetailModal.responseResult">响应结果</h3>
                        <button class="btn-ghost" type="button" onclick="copyDetailBlock('detail-response', this)" data-i18n="mcpDetailModal.copyContent">复制内容</button>
                    </div>
                    <div class="detail-code-card">
                        <pre id="detail-response" class="code-block"></pre>
                    </div>
                </div>
                <div class="detail-section detail-success-wrapper" id="detail-success-section" style="display: none;">
                    <div class="detail-section-header">
                        <h3 data-i18n="mcpDetailModal.correctInfo">正确信息</h3>
                        <button class="btn-ghost" type="button" onclick="copyDetailBlock('detail-success', this)" data-i18n="mcpDetailModal.copyContent">复制内容</button>
                    </div>
                    <div class="detail-code-card">
                        <pre id="detail-success" class="code-block"></pre>
                    </div>
                </div>
                <div class="detail-section detail-error-wrapper" id="detail-error-section" style="display: none;">
                    <div class="detail-section-header">
                        <h3 data-i18n="mcpDetailModal.errorInfo">错误信息</h3>
                        <button class="btn-ghost" type="button" onclick="copyDetailBlock('detail-error', this)" data-i18n="mcpDetailModal.copyError">复制错误</button>
                    </div>
                    <div class="detail-code-card">
                        <pre id="detail-error" class="code-block error"></pre>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 用户中断并说明（继续迭代） -->
    <div id="user-interrupt-modal" class="modal">
        <div class="modal-content" style="max-width: 520px;">
            <div class="modal-header">
                <h2 data-i18n="tasks.interruptModalTitle">中断当前步骤</h2>
                <span class="modal-close" onclick="closeUserInterruptModal()">&times;</span>
            </div>
            <div class="modal-body">
                <p class="detail-abort-hint" data-i18n="tasks.interruptModalHint">填写说明后将写入对话并由智能体继续迭代。</p>
                <div class="form-group">
                    <label for="user-interrupt-reason"><span data-i18n="tasks.interruptReasonLabel">中断说明</span></label>
                    <textarea id="user-interrupt-reason" class="form-control" rows="4" data-i18n="tasks.interruptReasonPlaceholder" data-i18n-attr="placeholder" placeholder=""></textarea>
                </div>
                <div class="form-actions" style="display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end;">
                    <button type="button" class="btn-secondary" onclick="closeUserInterruptModal()" data-i18n="tasks.interruptModalClose">关闭</button>
                    <button type="button" class="btn-secondary btn-delete" onclick="submitUserInterruptHardCancel()" data-i18n="tasks.interruptHardStop">彻底停止</button>
                    <button type="button" class="btn-primary" onclick="submitUserInterruptContinue()" data-i18n="tasks.interruptConfirmContinue">中断并继续</button>
                </div>
            </div>
        </div>
    </div>

    <!-- MCP 工具终止：可填写给模型的说明 -->
    <div id="mcp-tool-abort-modal" class="modal">
        <div class="modal-content" style="max-width: 520px;">
            <div class="modal-header">
                <h2 data-i18n="mcpDetailModal.abortNoteModalTitle">终止工具并补充说明</h2>
                <span class="modal-close" onclick="closeMcpToolAbortModal()">&times;</span>
            </div>
            <div class="modal-body">
                <p class="detail-abort-hint" data-i18n="mcpDetailModal.abortNoteModalHint">可选说明。</p>
                <div class="form-group">
                    <label for="mcp-tool-abort-note"><span data-i18n="mcpDetailModal.abortNoteLabel">终止说明（可选）</span></label>
                    <textarea id="mcp-tool-abort-note" class="form-control" rows="4" data-i18n="mcpDetailModal.abortNotePlaceholder" data-i18n-attr="placeholder" placeholder=""></textarea>
                </div>
                <div class="form-actions" style="display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end;">
                    <button type="button" class="btn-secondary" onclick="closeMcpToolAbortModal()" data-i18n="mcpDetailModal.abortNoteClose">取消</button>
                    <button type="button" class="btn-primary" onclick="submitMcpToolAbortModal()" data-i18n="mcpDetailModal.abortNoteSubmit">提交终止</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 外部MCP配置模态框 -->
    <div id="external-mcp-modal" class="modal">
        <div class="modal-content" style="max-width: 900px;">
            <div class="modal-header">
                <h2 id="external-mcp-modal-title" data-i18n="mcp.addExternalMCP">添加外部MCP</h2>
                <span class="modal-close" onclick="closeExternalMCPModal()">&times;</span>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="external-mcp-json"><span data-i18n="externalMcpModal.configJson">配置JSON</span> <span style="color: red;">*</span></label>
                    <textarea id="external-mcp-json" rows="15" data-i18n="externalMcpModal.placeholder" data-i18n-attr="placeholder" style="font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.875rem; line-height: 1.5;"></textarea>
                    <div class="password-hint">
                        <strong data-i18n="externalMcpModal.formatLabel">配置格式：</strong><span data-i18n="externalMcpModal.formatDesc">JSON对象，key为配置名称，value为配置内容。状态通过"启动/停止"按钮控制，无需在JSON中配置。</span><br>
                        <strong data-i18n="externalMcpModal.configExample">配置示例：</strong><br>
                        <strong data-i18n="externalMcpModal.stdioMode">stdio模式：</strong><br>
                        <code data-i18n="externalMcpModal.exampleStdio" style="display: block; margin: 8px 0; padding: 8px; background: var(--bg-secondary); border-radius: 4px; white-space: pre-wrap;">{
  "hexstrike-ai": {
    "command": "python3",
    "args": ["/path/to/script.py", "--server", "http://example.com"],
    "description": "描述",
    "timeout": 300
  }
}</code>
                        <strong data-i18n="externalMcpModal.httpMode">HTTP模式：</strong><br>
                        <code data-i18n="externalMcpModal.exampleHttp" style="display: block; margin: 8px 0; padding: 8px; background: var(--bg-secondary); border-radius: 4px; white-space: pre-wrap;">{
  "cyberstrike-ai-http": {
    "transport": "http",
    "url": "http://127.0.0.1:8081/mcp"
  }
}</code>
                        <strong data-i18n="externalMcpModal.sseMode">SSE模式：</strong><br>
                        <code data-i18n="externalMcpModal.exampleSse" style="display: block; margin: 8px 0; padding: 8px; background: var(--bg-secondary); border-radius: 4px; white-space: pre-wrap;">{
  "cyberstrike-ai-sse": {
    "transport": "sse",
    "url": "http://127.0.0.1:8081/mcp/sse"
  }
}</code>
                    </div>
                    <div id="external-mcp-json-error" class="error-message" style="display: none; margin-top: 8px; padding: 8px; background: rgba(220, 53, 69, 0.1); border: 1px solid rgba(220, 53, 69, 0.3); border-radius: 4px; color: var(--error-color); font-size: 0.875rem;"></div>
                </div>
                <div class="form-group">
                    <button type="button" class="btn-secondary" onclick="formatExternalMCPJSON()" style="margin-top: 8px;" data-i18n="externalMcpModal.formatJson">格式化JSON</button>
                    <button type="button" class="btn-secondary" onclick="loadExternalMCPExample()" style="margin-top: 8px; margin-left: 8px;" data-i18n="externalMcpModal.loadExample">加载示例</button>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-secondary" onclick="closeExternalMCPModal()" data-i18n="common.cancel">取消</button>
                <button class="btn-primary" onclick="saveExternalMCP()" data-i18n="common.save">保存</button>
            </div>
        </div>
    </div>

    <!-- 攻击链可视化模态框 -->
    <div id="attack-chain-modal" class="modal">
        <div class="modal-content attack-chain-modal-content">
            <div class="modal-header">
                <h2 data-i18n="attackChainModal.title">攻击链可视化</h2>
                <div class="modal-header-actions">
                    <button class="btn-primary attack-chain-action-btn" onclick="regenerateAttackChain()" data-i18n="attackChainModal.regenerateTitle" data-i18n-attr="title" data-i18n-skip-text="true" title="重新生成攻击链（包含最新对话内容）">
                        <span data-i18n="attackChainModal.regenerate">重新生成</span>
                    </button>
                    <button class="btn-secondary attack-chain-action-btn" onclick="exportAttackChain('png')" data-i18n="attackChainModal.exportPng" data-i18n-attr="title" title="导出为PNG">
                        📥 PNG
                    </button>
                    <button class="btn-secondary attack-chain-action-btn" onclick="exportAttackChain('svg')" data-i18n="attackChainModal.exportSvg" data-i18n-attr="title" title="导出为SVG">
                        📥 SVG
                    </button>
                    <button class="btn-secondary attack-chain-action-btn" onclick="refreshAttackChain()" data-i18n="attackChainModal.refreshTitle" data-i18n-attr="title" title="刷新当前攻击链（不重新生成）">
                        <span data-i18n="common.refresh">刷新</span>
                    </button>
                    <span class="modal-close" onclick="closeAttackChainModal()">&times;</span>
                </div>
            </div>
            <div class="modal-body attack-chain-body">
                <div class="attack-chain-main-layout">
                    <div class="attack-chain-visualization-area">
                        <div class="attack-chain-toolbar">
                            <div class="attack-chain-info">
                                <span id="attack-chain-stats">Nodes: 0 | Edges: 0</span>
                            </div>
                            <div class="attack-chain-filters">
                                <input type="text" id="attack-chain-search" data-i18n="attackChainModal.searchPlaceholder" data-i18n-attr="placeholder" placeholder="搜索节点..." 
                                       oninput="filterAttackChainNodes(this.value)">
                                <select id="attack-chain-type-filter" 
                                        onchange="filterAttackChainByType(this.value)">
                                    <option value="all" data-i18n="attackChainModal.allTypes">所有类型</option>
                                    <option value="target" data-i18n="attackChainModal.target">目标</option>
                                    <option value="action" data-i18n="attackChainModal.action">行动</option>
                                    <option value="vulnerability" data-i18n="attackChainModal.vulnerability">漏洞</option>
                                </select>
                                <select id="attack-chain-risk-filter"
                                        onchange="filterAttackChainByRisk(this.value)">
                                    <option value="all" data-i18n="attackChainModal.allRisks">所有风险</option>
                                    <option value="high" data-i18n="attackChainModal.highRisk">高风险 (80-100)</option>
                                    <option value="medium-high" data-i18n="attackChainModal.mediumHighRisk">中高风险 (60-79)</option>
                                    <option value="medium" data-i18n="attackChainModal.mediumRisk">中风险 (40-59)</option>
                                    <option value="low" data-i18n="attackChainModal.lowRisk">低风险 (0-39)</option>
                                </select>
                                <button class="btn-secondary" onclick="resetAttackChainFilters()" data-i18n="attackChainModal.resetFilter">
                                    重置筛选
                                </button>
                            </div>
                        </div>
                        <div id="attack-chain-container" class="attack-chain-container">
                            <div class="loading-spinner" data-i18n="attackChainModal.loading">加载中...</div>
                        </div>
                    </div>
                    <div class="attack-chain-sidebar">
                        <div class="attack-chain-sidebar-content">
                            <div class="attack-chain-legend">
                                <div class="legend-section">
                                    <div class="legend-title" data-i18n="attackChainModal.riskLevel">风险等级</div>
                                    <div class="legend-item">
                                        <span class="legend-color" style="background: #ff4444;"></span>
                                        <span data-i18n="attackChainModal.highRisk">高风险 (80-100)</span>
                                    </div>
                                    <div class="legend-item">
                                        <span class="legend-color" style="background: #ff8800;"></span>
                                        <span data-i18n="attackChainModal.mediumHighRisk">中高风险 (60-79)</span>
                                    </div>
                                    <div class="legend-item">
                                        <span class="legend-color" style="background: #ffbb00;"></span>
                                        <span data-i18n="attackChainModal.mediumRisk">中风险 (40-59)</span>
                                    </div>
                                    <div class="legend-item">
                                        <span class="legend-color" style="background: #88cc00;"></span>
                                        <span data-i18n="attackChainModal.lowRisk">低风险 (0-39)</span>
                                    </div>
                                </div>
                                <div class="legend-section">
                                    <div class="legend-title" data-i18n="attackChainModal.lineMeaning">连接线含义</div>
                                    <div class="legend-item">
                                        <span class="legend-line" style="border-top: 2px solid #42a5f5;"></span>
                                        <span data-i18n="attackChainModal.blueLine">蓝色线：行动发现漏洞</span>
                                    </div>
                                    <div class="legend-item">
                                        <span class="legend-line" style="border-top: 2px solid #e53935;"></span>
                                        <span data-i18n="attackChainModal.redLine">红色线：使能/促成关系</span>
                                    </div>
                                    <div class="legend-item">
                                        <span class="legend-line" style="border-top: 2px solid #616161;"></span>
                                        <span data-i18n="attackChainModal.grayLine">灰色线：逻辑顺序</span>
                                    </div>
                                </div>
                                <div id="attack-chain-details" class="legend-section attack-chain-details" style="display: none;">
                                    <div class="legend-title attack-chain-details-title">
                                        <span data-i18n="attackChainModal.nodeDetails">节点详情</span>
                                        <button class="attack-chain-details-close" onclick="closeNodeDetails()" data-i18n="attackChainModal.closeDetails" data-i18n-attr="title" title="关闭详情">
                                            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                <path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                                            </svg>
                                        </button>
                                    </div>
                                    <div id="attack-chain-details-content" class="attack-chain-details-content"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div id="chat-files-edit-modal" class="modal">
        <div class="modal-content" style="max-width: 720px;">
            <div class="modal-header">
                <h2 data-i18n="chatFilesPage.editTitle">编辑文件</h2>
                <span class="modal-close" onclick="closeChatFilesEditModal()">&times;</span>
            </div>
            <div class="modal-body">
                <p class="chat-files-modal-path"><code id="chat-files-edit-path"></code></p>
                <textarea id="chat-files-edit-textarea" class="form-control chat-files-edit-textarea" rows="18"></textarea>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn-secondary" onclick="closeChatFilesEditModal()" data-i18n="common.cancel">取消</button>
                <button type="button" class="btn-primary" onclick="saveChatFilesEdit()" data-i18n="common.save">保存</button>
            </div>
        </div>
    </div>

    <div id="chat-files-rename-modal" class="modal chat-files-form-modal">
        <div class="modal-content chat-files-form-modal-content chat-files-mkdir-modal-content">
            <div class="modal-header chat-files-form-modal-header">
                <h2 data-i18n="chatFilesPage.renameTitle">重命名</h2>
                <span class="modal-close chat-files-form-modal-close" onclick="closeChatFilesRenameModal()" aria-label="Close">&times;</span>
            </div>
            <div class="modal-body chat-files-mkdir-body">
                <div class="chat-files-mkdir-location">
                    <div class="chat-files-mkdir-location-caption" data-i18n="chatFilesPage.renameCurrentFile">当前文件</div>
                    <div class="chat-files-mkdir-path-box">
                        <code class="chat-files-mkdir-path" id="chat-files-rename-path-hint"></code>
                    </div>
                </div>
                <label class="chat-files-rename-label chat-files-mkdir-label">
                    <span class="chat-files-mkdir-field-name">
                        <svg class="chat-files-mkdir-field-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
                        <span data-i18n="chatFilesPage.newFileName">新文件名</span>
                    </span>
                    <input type="text" id="chat-files-rename-input" class="form-control chat-files-mkdir-input" autocomplete="off" />
                </label>
            </div>
            <div class="modal-footer chat-files-mkdir-footer">
                <button type="button" class="btn-secondary chat-files-mkdir-btn-cancel" onclick="closeChatFilesRenameModal()" data-i18n="common.cancel">取消</button>
                <button type="button" class="btn-primary chat-files-mkdir-btn-submit" onclick="submitChatFilesRename()" data-i18n="common.ok">确定</button>
            </div>
        </div>
    </div>

    <div id="chat-files-mkdir-modal" class="modal chat-files-form-modal">
        <div class="modal-content chat-files-form-modal-content chat-files-mkdir-modal-content">
            <div class="modal-header chat-files-form-modal-header">
                <h2 data-i18n="chatFilesPage.newFolderTitle">新建文件夹</h2>
                <span class="modal-close chat-files-form-modal-close" onclick="closeChatFilesMkdirModal()" aria-label="Close">&times;</span>
            </div>
            <div class="modal-body chat-files-mkdir-body">
                <div class="chat-files-mkdir-location" aria-live="polite">
                    <div class="chat-files-mkdir-location-caption" data-i18n="chatFilesPage.newFolderLocation">位置</div>
                    <div class="chat-files-mkdir-path-box">
                        <code class="chat-files-mkdir-path" id="chat-files-mkdir-parent-hint">chat_uploads</code>
                    </div>
                </div>
                <label class="chat-files-rename-label chat-files-mkdir-label">
                    <span class="chat-files-mkdir-field-name">
                        <svg class="chat-files-mkdir-field-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
                        <span data-i18n="chatFilesPage.newFolderNameLabel">文件夹名称</span>
                    </span>
                    <input type="text" id="chat-files-mkdir-input" class="form-control chat-files-mkdir-input" data-i18n="chatFilesPage.newFolderNamePlaceholder" data-i18n-attr="placeholder" placeholder="仅名称，不含 /" autocomplete="off" />
                </label>
            </div>
            <div class="modal-footer chat-files-mkdir-footer">
                <button type="button" class="btn-secondary chat-files-mkdir-btn-cancel" onclick="closeChatFilesMkdirModal()" data-i18n="common.cancel">取消</button>
                <button type="button" class="btn-primary chat-files-mkdir-btn-submit" onclick="submitChatFilesMkdir()" data-i18n="common.ok">确定</button>
            </div>
        </div>
    </div>

    <!-- Marked.js for Markdown parsing -->
    <script src="https://cdn.jsdelivr.net/npm/marked@11.1.1/marked.min.js"></script>
    <!-- DOMPurify for HTML sanitization to prevent XSS -->
    <script src="https://cdn.jsdelivr.net/npm/dompurify@3.0.8/dist/purify.min.js"></script>
    <!-- Cytoscape.js for attack chain visualization -->
    <script src="https://cdn.jsdelivr.net/npm/cytoscape@3.27.0/dist/cytoscape.min.js"></script>
    <!-- ELK.js for high-quality DAG layout (reduces edge crossings) -->
    <script src="https://cdn.jsdelivr.net/npm/elkjs@0.9.2/lib/elk.bundled.js"></script>
    <!-- SheetJS for XLSX export (info-collect) -->
    <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
    <script>
        // 确保ELK对象全局可用
        if (typeof ELK === 'undefined' && typeof elk !== 'undefined') {
            window.ELK = elk;
        }
    </script>
    <!-- 知识项编辑模态框 -->
    <!-- Skill模态框 -->
    <div id="skill-modal" class="modal">
        <div class="modal-content" style="max-width: 1100px;">
            <div class="modal-header">
                <h2 id="skill-modal-title" data-i18n="skillModal.addSkill">添加Skill</h2>
                <span class="modal-close" onclick="closeSkillModal()">&times;</span>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="skill-name"><span data-i18n="skillModal.skillName">Skill名称</span> <span style="color: red;">*</span></label>
                    <input type="text" id="skill-name" data-i18n="skillModal.skillNamePlaceholder" data-i18n-attr="placeholder" placeholder="例如: sql-injection-testing" required />
                    <small class="form-hint" data-i18n="skillModal.skillNameHint">小写字母、数字、连字符（与 Agent Skills 的 name 一致）</small>
                </div>
                <div class="form-group">
                    <label for="skill-description"><span data-i18n="skillModal.description">描述</span> <span style="color: red;">*</span></label>
                    <input type="text" id="skill-description" data-i18n="skillModal.descriptionPlaceholder" data-i18n-attr="placeholder" placeholder="Skill的简短描述" required />
                    <small class="form-hint" data-i18n="skillModal.descriptionHint">写入 SKILL.md 的 YAML front matter（description 字段）</small>
                </div>
                <div class="form-group" id="skill-package-editor" style="display: none;">
                    <label data-i18n="skillModal.packageFiles">包内文件（标准 Agent Skills 布局）</label>
                    <div style="display: flex; gap: 12px; align-items: flex-start; min-height: 300px;">
                        <div id="skill-package-tree" style="flex: 0 0 240px; max-height: 440px; overflow: auto; border: 1px solid rgba(127,127,127,0.25); border-radius: 6px; padding: 8px; font-size: 13px; line-height: 1.4;"></div>
                        <div style="flex: 1; min-width: 0;">
                            <div style="margin-bottom: 8px; font-size: 13px;">
                                <span data-i18n="skillModal.editingFile">正在编辑</span> <code id="skill-active-path">SKILL.md</code>
                            </div>
                            <div id="skill-new-file-row" style="display: flex; gap: 8px; margin-bottom: 8px; align-items: center;">
                                <input type="text" id="skill-new-file-path" data-i18n="skillModal.newFilePlaceholder" data-i18n-attr="placeholder" placeholder="新文件路径，如 FORMS.md" style="flex: 1;" />
                                <button type="button" class="btn-secondary btn-small" id="skill-new-file-btn" data-i18n="skillModal.newFile">新建文件</button>
                            </div>
                            <label for="skill-content"><span data-i18n="skillModal.contentLabel">内容</span> <span style="color: red;">*</span></label>
                            <textarea id="skill-content" rows="18" data-i18n="skillModal.contentPlaceholder" data-i18n-attr="placeholder" placeholder="输入skill内容，支持Markdown格式..." style="font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.875rem; line-height: 1.5; width: 100%; box-sizing: border-box;" required></textarea>
                            <small class="form-hint" id="skill-body-hint-edit" data-i18n="skillModal.bodyHintEdit" style="display: none;">选择 SKILL.md 时，此处为正文（不含 YAML 头）；保存时与上方描述一并写回标准 SKILL.md。</small>
                        </div>
                    </div>
                </div>
                <div class="form-group" id="skill-add-editor">
                    <label for="skill-content-add"><span data-i18n="skillModal.contentLabel">正文（Markdown）</span> <span style="color: red;">*</span></label>
                    <textarea id="skill-content-add" rows="18" data-i18n="skillModal.contentPlaceholderAdd" data-i18n-attr="placeholder" placeholder="SKILL.md 正文（无需手写 front matter，由名称与描述自动生成）..." style="font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.875rem; line-height: 1.5; width: 100%; box-sizing: border-box;" required></textarea>
                    <small class="form-hint" data-i18n="skillModal.contentHintAdd">创建时只需填写正文；保存后生成标准 SKILL.md（含 YAML 头）。开源技能包可直接放入 skills/&lt;name&gt;/ 使用。</small>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-secondary" onclick="closeSkillModal()" data-i18n="common.cancel">取消</button>
                <button class="btn-primary" onclick="saveSkill()" data-i18n="common.save">保存</button>
            </div>
        </div>
    </div>

    <div id="knowledge-item-modal" class="modal">
        <div class="modal-content" style="max-width: 900px;">
            <div class="modal-header">
                <h2 id="knowledge-item-modal-title">添加知识</h2>
                <span class="modal-close" onclick="closeKnowledgeItemModal()">&times;</span>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="knowledge-item-category">分类（风险类型）<span style="color: red;">*</span></label>
                    <input type="text" id="knowledge-item-category" placeholder="例如：SQL注入" required />
                </div>
                <div class="form-group">
                    <label for="knowledge-item-title">标题<span style="color: red;">*</span></label>
                    <input type="text" id="knowledge-item-title" placeholder="知识项标题" required />
                </div>
                <div class="form-group">
                    <label for="knowledge-item-content">内容（Markdown格式）<span style="color: red;">*</span></label>
                    <textarea id="knowledge-item-content" rows="20" placeholder="输入知识内容，支持Markdown格式..." style="font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.875rem; line-height: 1.5;" required></textarea>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-secondary" onclick="closeKnowledgeItemModal()">取消</button>
                <button class="btn-primary" onclick="saveKnowledgeItem()">保存</button>
            </div>
        </div>
    </div>

    <!-- 批量管理对话模态框 -->
    <div id="batch-manage-modal" class="modal">
        <div class="modal-content batch-manage-modal-content">
            <div class="modal-header">
                <h2 id="batch-manage-title">管理对话记录·共<span id="batch-manage-count">0</span>条</h2>
                <div class="batch-manage-header-actions">
                    <div class="batch-search-box">
                        <input type="text" id="batch-search-input" data-i18n="batchManageModal.searchPlaceholder" data-i18n-attr="placeholder" placeholder="搜索历史记录" oninput="filterBatchConversations(this.value)" />
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <circle cx="11" cy="11" r="8" stroke="currentColor" stroke-width="2"/>
                            <path d="m21 21-4.35-4.35" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                        </svg>
                    </div>
                    <span class="modal-close" onclick="closeBatchManageModal()">&times;</span>
                </div>
            </div>
            <div class="modal-body batch-manage-body">
                <div class="batch-conversations-table">
                    <div class="batch-table-header">
                        <div class="batch-table-col-checkbox"></div>
                        <div class="batch-table-col-name" data-i18n="batchManageModal.conversationName">对话名称</div>
                        <div class="batch-table-col-time" data-i18n="batchManageModal.lastTime">最近一次对话时间</div>
                        <div class="batch-table-col-action" data-i18n="batchManageModal.action">操作</div>
                    </div>
                    <div id="batch-conversations-list" class="batch-conversations-list"></div>
                </div>
            </div>
            <div class="modal-footer batch-manage-footer">
                <label class="select-all-checkbox">
                    <input type="checkbox" id="batch-select-all" onchange="toggleSelectAllBatch()" />
                    <span data-i18n="batchManageModal.selectAll">全选</span>
                </label>
                <div class="batch-footer-actions">
                    <button class="btn-secondary" onclick="closeBatchManageModal()" data-i18n="common.cancel">取消</button>
                    <button class="btn-primary" onclick="deleteSelectedConversations()" data-i18n="batchManageModal.deleteSelected">删除所选</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 创建分组模态框 -->
    <div id="create-group-modal" class="modal">
        <div class="modal-content create-group-modal-content">
            <div class="modal-header">
                <h2 data-i18n="createGroupModal.title">创建分组</h2>
                <span class="modal-close" onclick="closeCreateGroupModal()">&times;</span>
            </div>
            <div class="modal-body create-group-body">
                <p class="create-group-description" data-i18n="createGroupModal.description">分组功能可将对话集中归类管理，让对话更加井然有序。</p>
                <div class="create-group-input-wrapper">
                    <button type="button" class="group-icon-input" id="create-group-icon-btn" onclick="toggleGroupIconPicker()" data-i18n="createGroupModal.selectIcon" data-i18n-attr="title" title="点击选择图标">📁</button>
                    <input type="text" id="create-group-name-input" data-i18n="createGroupModal.groupNamePlaceholder" data-i18n-attr="placeholder" placeholder="请输入分组名称" />
                    <!-- Emoji选择器面板 -->
                    <div id="group-icon-picker" class="group-icon-picker" style="display: none;">
                        <div class="icon-picker-header">
                            <span data-i18n="createGroupModal.pickIcon">选择图标</span>
                            <div class="icon-picker-custom">
                                <input type="text" id="custom-icon-input" class="custom-icon-input" data-i18n="createGroupModal.customIcon" data-i18n-attr="placeholder" placeholder="自定义" maxlength="2" />
                                <button type="button" class="custom-icon-btn" onclick="applyCustomIcon()" data-i18n="createGroupModal.confirmIcon">确定</button>
                            </div>
                        </div>
                        <div class="icon-picker-grid">
                            <span class="icon-option" onclick="selectGroupIcon('📁')">📁</span>
                            <span class="icon-option" onclick="selectGroupIcon('🔒')">🔒</span>
                            <span class="icon-option" onclick="selectGroupIcon('🛡️')">🛡️</span>
                            <span class="icon-option" onclick="selectGroupIcon('⚔️')">⚔️</span>
                            <span class="icon-option" onclick="selectGroupIcon('🎯')">🎯</span>
                            <span class="icon-option" onclick="selectGroupIcon('🔍')">🔍</span>
                            <span class="icon-option" onclick="selectGroupIcon('💻')">💻</span>
                            <span class="icon-option" onclick="selectGroupIcon('🐛')">🐛</span>
                            <span class="icon-option" onclick="selectGroupIcon('🚀')">🚀</span>
                            <span class="icon-option" onclick="selectGroupIcon('⚡')">⚡</span>
                            <span class="icon-option" onclick="selectGroupIcon('🔥')">🔥</span>
                            <span class="icon-option" onclick="selectGroupIcon('💡')">💡</span>
                            <span class="icon-option" onclick="selectGroupIcon('🎮')">🎮</span>
                            <span class="icon-option" onclick="selectGroupIcon('🏴‍☠️')">🏴‍☠️</span>
                            <span class="icon-option" onclick="selectGroupIcon('🕵️')">🕵️</span>
                            <span class="icon-option" onclick="selectGroupIcon('🔑')">🔑</span>
                            <span class="icon-option" onclick="selectGroupIcon('📡')">📡</span>
                            <span class="icon-option" onclick="selectGroupIcon('🌐')">🌐</span>
                            <span class="icon-option" onclick="selectGroupIcon('📊')">📊</span>
                            <span class="icon-option" onclick="selectGroupIcon('📝')">📝</span>
                            <span class="icon-option" onclick="selectGroupIcon('🗂️')">🗂️</span>
                            <span class="icon-option" onclick="selectGroupIcon('📌')">📌</span>
                            <span class="icon-option" onclick="selectGroupIcon('⭐')">⭐</span>
                            <span class="icon-option" onclick="selectGroupIcon('💎')">💎</span>
                        </div>
                    </div>
                </div>
                <div class="create-group-suggestions">
                    <div class="suggestion-tag" data-i18n="createGroupModal.suggestionPenetrationTest" onclick="selectSuggestionByKey('createGroupModal.suggestionPenetrationTest')">渗透测试</div>
                    <div class="suggestion-tag" data-i18n="createGroupModal.suggestionCtf" onclick="selectSuggestionByKey('createGroupModal.suggestionCtf')">CTF</div>
                    <div class="suggestion-tag" data-i18n="createGroupModal.suggestionRedTeam" onclick="selectSuggestionByKey('createGroupModal.suggestionRedTeam')">红队</div>
                    <div class="suggestion-tag" data-i18n="createGroupModal.suggestionVulnerabilityMining" onclick="selectSuggestionByKey('createGroupModal.suggestionVulnerabilityMining')">漏洞挖掘</div>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-secondary" onclick="closeCreateGroupModal()" data-i18n="createGroupModal.cancel">取消</button>
                <button class="btn-primary" onclick="createGroup(event)" data-i18n="createGroupModal.create">创建</button>
            </div>
        </div>
    </div>

    <!-- 上下文菜单 -->
    <div id="conversation-context-menu" class="context-menu" style="display: none;">
        <div id="attack-chain-menu-item" class="context-menu-item" onclick="showAttackChainFromContext()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M10.5 13.5l3-3M8 8H5a4 4 0 1 0 0 8h3m8-8h3a4 4 0 0 1 0 8h-3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span data-i18n="contextMenu.viewAttackChain">查看攻击链</span>
        </div>
        <div class="context-menu-item context-menu-item-has-submenu" onmouseenter="handleDownloadMarkdownSubmenuEnter()" onmouseleave="handleDownloadMarkdownSubmenuLeave(event)">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 3v12m0 0l-4-4m4 4l4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                <path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span data-i18n="contextMenu.downloadMarkdown">下载 Markdown</span>
            <svg class="submenu-arrow" width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <div id="download-markdown-submenu" class="context-submenu" style="display: none;" onmouseenter="clearDownloadMarkdownSubmenuHideTimeout()" onmouseleave="hideDownloadMarkdownSubmenu()">
                <div class="context-submenu-item" onclick="downloadConversationMarkdownFromContext(false)">
                    <span data-i18n="contextMenu.downloadMarkdownSummary">简版</span>
                </div>
                <div class="context-submenu-item" onclick="downloadConversationMarkdownFromContext(true)">
                    <span data-i18n="contextMenu.downloadMarkdownFull">完整版</span>
                </div>
            </div>
        </div>
        <div class="context-menu-item" onclick="navigateToVulnerabilitiesForContextConversation()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                <path d="M9 12l2 2 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span data-i18n="contextMenu.viewVulnerabilities">查看漏洞</span>
        </div>
        <div class="context-menu-divider"></div>
        <div class="context-menu-item" onclick="renameConversation()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span data-i18n="contextMenu.rename">重命名</span>
        </div>
        <div class="context-menu-item" onclick="pinConversation()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 17v5M5 17h14l-1-7H6l-1 7zM9 10V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span id="pin-conversation-menu-text" data-i18n="contextMenu.pinConversation">置顶此对话</span>
        </div>
        <div class="context-menu-item" onclick="showBatchManageModal()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <line x1="3" y1="12" x2="21" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                <line x1="3" y1="6" x2="21" y2="6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                <line x1="3" y1="18" x2="21" y2="18" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                <circle cx="8" cy="6" r="1" fill="currentColor"/>
                <circle cx="8" cy="12" r="1" fill="currentColor"/>
                <circle cx="8" cy="18" r="1" fill="currentColor"/>
            </svg>
            <span data-i18n="contextMenu.batchManage">批量管理</span>
        </div>
        <div class="context-menu-item context-menu-item-has-submenu" onmouseenter="handleMoveToGroupSubmenuEnter()" onmouseleave="handleMoveToGroupSubmenuLeave(event)">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span data-i18n="contextMenu.moveToGroup">移动到分组</span>
            <svg class="submenu-arrow" width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <div id="move-to-group-submenu" class="context-submenu" style="display: none;" onmouseenter="clearSubmenuHideTimeout()" onmouseleave="hideMoveToGroupSubmenu()"></div>
        </div>
        <div class="context-menu-divider"></div>
        <div class="context-menu-item context-menu-item-danger" onclick="deleteConversationFromContext()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2m3 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6h14z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span data-i18n="contextMenu.deleteConversation">删除此对话</span>
        </div>
    </div>

    <!-- 分组上下文菜单 -->
    <div id="group-context-menu" class="context-menu" style="display: none;">
        <div class="context-menu-item" onclick="renameGroupFromContext()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span data-i18n="contextMenu.rename">重命名</span>
        </div>
        <div class="context-menu-item" onclick="pinGroupFromContext()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 17v5M5 17h14l-1-7H6l-1 7zM9 10V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span id="pin-group-menu-text" data-i18n="contextMenu.pinGroup">置顶此分组</span>
        </div>
        <div class="context-menu-item context-menu-item-danger" onclick="deleteGroupFromContext()">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2m3 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6h14z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
            <span data-i18n="contextMenu.deleteGroup">删除此分组</span>
        </div>
    </div>

    <!-- 新建任务模态框 -->
    <div id="batch-import-modal" class="modal">
        <div class="modal-content" style="max-width: 800px;">
            <div class="modal-header">
                <h2 data-i18n="batchImportModal.title">新建任务</h2>
                <span class="modal-close" onclick="closeBatchImportModal()">&times;</span>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="batch-queue-title" data-i18n="batchImportModal.queueTitle">任务标题</label>
                    <input type="text" id="batch-queue-title" data-i18n="batchImportModal.queueTitlePlaceholder" data-i18n-attr="placeholder" placeholder="请输入任务标题（可选，用于标识和筛选）" />
                    <div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.queueTitleHint">为批量任务队列设置一个标题，方便后续查找和管理。</div>
                </div>
                <div class="form-group">
                    <label for="batch-queue-role" data-i18n="batchImportModal.role">角色</label>
                    <select id="batch-queue-role" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 0.875rem;">
                        <option value="" data-i18n="batchImportModal.defaultRole">默认</option>
                    </select>
                    <div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.roleHint">选择一个角色，所有任务将使用该角色的配置（提示词和工具）执行。</div>
                </div>
                <div class="form-group">
                    <label for="batch-queue-project-id" data-i18n="batchImportModal.project">所属项目</label>
                    <select id="batch-queue-project-id" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 0.875rem;">
                        <option value="" data-i18n="batchImportModal.projectNone">（未绑定）</option>
                    </select>
                    <div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.projectHint">可为队列绑定项目；留空则不绑定项目上下文。</div>
                </div>
                <div class="form-group">
                    <label for="batch-queue-agent-mode" data-i18n="batchImportModal.agentMode">代理模式</label>
                    <select id="batch-queue-agent-mode" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 0.875rem;">
                        <option value="single" data-i18n="chat.agentModeReactNative">原生 ReAct 模式</option>
                        <option value="eino_single" data-i18n="chat.agentModeEinoSingle">Eino 单代理（ADK）</option>
                        <option value="deep" data-i18n="chat.agentModeDeep">Deep（DeepAgent）</option>
                        <option value="plan_execute" data-i18n="chat.agentModePlanExecuteLabel">Plan-Execute</option>
                        <option value="supervisor" data-i18n="chat.agentModeSupervisorLabel">Supervisor</option>
                    </select>
                    <div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.agentModeHint">与对话页一致：原生 ReAct、Eino 单代理（ADK），或 Deep / Plan-Execute / Supervisor（后三种需已启用多代理）。</div>
                </div>
                <div class="form-group">
                    <label for="batch-queue-schedule-mode" data-i18n="batchImportModal.scheduleMode">调度方式</label>
                    <select id="batch-queue-schedule-mode" onchange="handleBatchScheduleModeChange()" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 0.875rem;">
                        <option value="manual" data-i18n="batchImportModal.scheduleModeManual">手工执行</option>
                        <option value="cron" data-i18n="batchImportModal.scheduleModeCron">调度表达式（Cron）</option>
                    </select>
                    <div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.scheduleModeHint">手工执行用于一次性任务；Cron 用于周期任务，建议先手工验证任务正确性。</div>
                </div>
                <div class="form-group" id="batch-queue-cron-group" style="display: none;">
                    <label for="batch-queue-cron-expr"><span data-i18n="batchImportModal.cronExpr">Cron 表达式</span><span style="color: red;">*</span></label>
                    <input type="text" id="batch-queue-cron-expr" data-i18n="batchImportModal.cronExprPlaceholder" data-i18n-attr="placeholder" placeholder="例如：0 */2 * * *（每2小时执行一次）" />
                    <div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.cronExprHint">采用标准 5 段 Cron：分 时 日 月 周，例如 `0 2 * * *` 表示每天 02:00 执行。</div>
                </div>
                <div class="form-group">
                    <label for="batch-queue-execute-now" class="batch-execute-now-label">
                        <input type="checkbox" id="batch-queue-execute-now" />
                        <span data-i18n="batchImportModal.executeNow">创建后立即执行</span>
                    </label>
                    <div class="form-hint" style="margin-top: 4px;" data-i18n="batchImportModal.executeNowHint">默认不立即执行；关闭后队列保持待执行，可在需要时手动开始。</div>
                </div>
                <div class="form-group">
                    <label for="batch-tasks-input"><span data-i18n="batchImportModal.tasksList">任务列表（每行一个任务）</span><span style="color: red;">*</span></label>
                    <textarea id="batch-tasks-input" rows="15" data-i18n="batchImportModal.tasksListPlaceholderExample" data-i18n-attr="placeholder" placeholder="请输入任务列表，每行一个任务，例如：&#10;扫描 192.168.1.1 的开放端口&#10;检查 https://example.com 是否存在SQL注入&#10;枚举 example.com 的子域名" style="font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.875rem; line-height: 1.5;"></textarea>
                    <div class="form-hint" style="margin-top: 8px;" data-i18n="batchImportModal.tasksListHintFull">提示：每行输入一个任务指令，系统将依次执行这些任务。空行会被自动忽略。</div>
                </div>
                <div class="form-group">
                    <div id="batch-import-stats" class="batch-import-stats"></div>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-secondary" onclick="closeBatchImportModal()" data-i18n="common.cancel">取消</button>
                <button class="btn-primary" onclick="createBatchQueue()" data-i18n="batchImportModal.createQueue">创建队列</button>
            </div>
        </div>
    </div>

    <!-- 批量任务队列详情模态框 -->
    <div id="batch-queue-detail-modal" class="modal">
        <div class="modal-content" style="max-width: 900px;">
            <div class="modal-header">
                <h2 id="batch-queue-detail-title" data-i18n="batchQueueDetailModal.title">批量任务队列详情</h2>
                <div style="display: flex; align-items: center; gap: 12px;">
                    <div class="modal-header-actions">
                        <button class="btn-secondary btn-small" id="batch-queue-add-task-btn" onclick="showAddBatchTaskModal()" style="display: none;" data-i18n="batchQueueDetailModal.addTask">添加任务</button>
                        <button class="btn-primary btn-small" id="batch-queue-start-btn" onclick="startBatchQueue()" style="display: none;" data-i18n="batchQueueDetailModal.startExecute">开始执行</button>
                        <button class="btn-primary btn-small" id="batch-queue-rerun-btn" onclick="rerunBatchQueue()" style="display: none;" data-i18n="batchQueueDetailModal.rerunQueue">重跑一轮</button>
                        <button class="btn-secondary btn-small" id="batch-queue-pause-btn" onclick="pauseBatchQueue()" style="display: none;" data-i18n="batchQueueDetailModal.pauseQueue">暂停队列</button>
                        <button class="btn-secondary btn-small btn-danger" id="batch-queue-delete-btn" onclick="deleteBatchQueue()" style="display: none;" data-i18n="batchQueueDetailModal.deleteQueue">删除队列</button>
                    </div>
                    <span class="modal-close" onclick="closeBatchQueueDetailModal()">&times;</span>
                </div>
            </div>
            <div class="modal-body">
                <div id="batch-queue-detail-content"></div>
            </div>
        </div>
    </div>

    <!-- 添加批量任务模态框 -->
    <div id="add-batch-task-modal" class="modal">
        <div class="modal-content" style="max-width: 600px;">
            <div class="modal-header">
                <h2 data-i18n="addBatchTaskModal.title">添加任务</h2>
                <span class="modal-close" onclick="closeAddBatchTaskModal()">&times;</span>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="add-task-message" data-i18n="addBatchTaskModal.taskMessage">任务消息</label>
                    <textarea id="add-task-message" class="form-control" rows="5" data-i18n="addBatchTaskModal.taskMessagePlaceholder" data-i18n-attr="placeholder" placeholder="请输入任务消息"></textarea>
                </div>
                <div class="form-actions">
                    <button class="btn-primary" onclick="saveAddBatchTask()" data-i18n="addBatchTaskModal.add">添加</button>
                    <button class="btn-secondary" onclick="closeAddBatchTaskModal()" data-i18n="common.cancel">取消</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 漏洞编辑模态框 -->
    <div id="vulnerability-modal" class="modal">
        <div class="modal-content" style="max-width: 900px;">
            <div class="modal-header">
                <h2 id="vulnerability-modal-title" data-i18n="vulnerability.addVuln">添加漏洞</h2>
                <span class="modal-close" onclick="closeVulnerabilityModal()">&times;</span>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="vulnerability-project-id" data-i18n="vulnerabilityModal.project">所属项目</label>
                    <select id="vulnerability-project-id" class="form-input">
                        <option value="" data-i18n="vulnerabilityModal.projectNone">（未绑定）</option>
                    </select>
                    <p class="form-hint" data-i18n="vulnerabilityModal.projectHint">绑定后 Agent 在项目范围内可通过 list_vulnerabilities 看到本条记录；留空则尝试从会话自动关联。</p>
                </div>
                <div class="form-group">
                    <label for="vulnerability-conversation-id"><span data-i18n="vulnerabilityModal.conversationId">会话ID</span> <span style="color: red;">*</span></label>
                    <input type="text" id="vulnerability-conversation-id" data-i18n="vulnerabilityModal.conversationIdPlaceholder" data-i18n-attr="placeholder" placeholder="输入会话ID" required />
                </div>
                <div class="form-group">
                    <label for="vulnerability-conversation-tag" data-i18n="vulnerabilityModal.conversationTag">对话标签</label>
                    <input type="text" id="vulnerability-conversation-tag" data-i18n="vulnerabilityModal.conversationTagPlaceholder" data-i18n-attr="placeholder" placeholder="如：红队演练A、客户A周报" />
                </div>
                <div class="form-group">
                    <label for="vulnerability-task-tag" data-i18n="vulnerabilityModal.taskTag">任务标签</label>
                    <input type="text" id="vulnerability-task-tag" data-i18n="vulnerabilityModal.taskTagPlaceholder" data-i18n-attr="placeholder" placeholder="如：批量扫描Q2、专项复测" />
                </div>
                <div class="form-group">
                    <label for="vulnerability-title"><span data-i18n="vulnerabilityModal.title">标题</span> <span style="color: red;">*</span></label>
                    <input type="text" id="vulnerability-title" data-i18n="vulnerabilityModal.titlePlaceholder" data-i18n-attr="placeholder" placeholder="漏洞标题" required />
                </div>
                <div class="form-group">
                    <label for="vulnerability-description" data-i18n="vulnerabilityModal.description">描述</label>
                    <textarea id="vulnerability-description" rows="5" data-i18n="vulnerabilityModal.descriptionPlaceholder" data-i18n-attr="placeholder" placeholder="漏洞详细描述"></textarea>
                </div>
                <div class="form-group">
                    <label for="vulnerability-severity"><span data-i18n="vulnerabilityModal.severity">严重程度</span> <span style="color: red;">*</span></label>
                    <select id="vulnerability-severity" required>
                        <option value="" data-i18n="vulnerabilityModal.pleaseSelect">请选择</option>
                        <option value="critical" data-i18n="vulnerabilityModal.severityCritical">严重</option>
                        <option value="high" data-i18n="vulnerabilityModal.severityHigh">高危</option>
                        <option value="medium" data-i18n="vulnerabilityModal.severityMedium">中危</option>
                        <option value="low" data-i18n="vulnerabilityModal.severityLow">低危</option>
                        <option value="info" data-i18n="vulnerabilityModal.severityInfo">信息</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="vulnerability-status" data-i18n="vulnerabilityModal.status">状态</label>
                    <select id="vulnerability-status">
                        <option value="open" data-i18n="vulnerabilityModal.statusOpen">待处理</option>
                        <option value="confirmed" data-i18n="vulnerabilityModal.statusConfirmed">已确认</option>
                        <option value="fixed" data-i18n="vulnerabilityModal.statusFixed">已修复</option>
                        <option value="false_positive" data-i18n="vulnerabilityModal.statusFalsePositive">误报</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="vulnerability-type" data-i18n="vulnerabilityModal.type">漏洞类型</label>
                    <input type="text" id="vulnerability-type" data-i18n="vulnerabilityModal.typePlaceholder" data-i18n-attr="placeholder" placeholder="如：SQL注入、XSS、CSRF等" />
                </div>
                <div class="form-group">
                    <label for="vulnerability-target" data-i18n="vulnerabilityModal.target">目标</label>
                    <input type="text" id="vulnerability-target" data-i18n="vulnerabilityModal.targetPlaceholder" data-i18n-attr="placeholder" placeholder="受影响的目标（URL、IP地址等）" />
                </div>
                <div class="form-group">
                    <label for="vulnerability-proof" data-i18n="vulnerabilityModal.proof">证明（POC）</label>
                    <textarea id="vulnerability-proof" rows="5" data-i18n="vulnerabilityModal.proofPlaceholder" data-i18n-attr="placeholder" placeholder="漏洞证明，如请求/响应、截图等"></textarea>
                </div>
                <div class="form-group">
                    <label for="vulnerability-impact" data-i18n="vulnerabilityModal.impact">影响</label>
                    <textarea id="vulnerability-impact" rows="3" data-i18n="vulnerabilityModal.impactPlaceholder" data-i18n-attr="placeholder" placeholder="漏洞影响说明"></textarea>
                </div>
                <div class="form-group">
                    <label for="vulnerability-recommendation" data-i18n="vulnerabilityModal.recommendation">修复建议</label>
                    <textarea id="vulnerability-recommendation" rows="3" data-i18n="vulnerabilityModal.recommendationPlaceholder" data-i18n-attr="placeholder" placeholder="修复建议"></textarea>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-secondary" onclick="closeVulnerabilityModal()" data-i18n="common.cancel">取消</button>
                <button class="btn-primary" onclick="saveVulnerability()" data-i18n="common.save">保存</button>
            </div>
        </div>
    </div>

    <!-- WebShell 添加连接模态框 -->
    <div id="webshell-modal" class="modal">
        <div class="modal-content" style="max-width: 560px;">
            <div class="modal-header">
                <h2 id="webshell-modal-title" data-i18n="webshell.addConnection">添加连接</h2>
                <span class="modal-close" onclick="closeWebshellModal()">&times;</span>
            </div>
            <div class="modal-body">
                <input type="hidden" id="webshell-edit-id" value="" />
                <div class="form-group">
                    <label for="webshell-url"><span data-i18n="webshell.url">Shell 地址</span> <span style="color: red;">*</span></label>
                    <input type="text" id="webshell-url" data-i18n="webshell.urlPlaceholder" data-i18n-attr="placeholder" placeholder="http(s)://target.com/shell.php" />
                </div>
                <div class="form-group">
                    <label for="webshell-password" data-i18n="webshell.password">连接密码/密钥</label>
                    <input type="text" id="webshell-password" data-i18n="webshell.passwordPlaceholder" data-i18n-attr="placeholder" placeholder="如冰蝎/蚁剑的连接密码" />
                </div>
                <div class="form-group">
                    <label for="webshell-type" data-i18n="webshell.type">Shell 类型</label>
                    <select id="webshell-type">
                        <option value="php" data-i18n="webshell.typePhp">PHP</option>
                        <option value="asp" data-i18n="webshell.typeAsp">ASP</option>
                        <option value="aspx" data-i18n="webshell.typeAspx">ASPX</option>
                        <option value="jsp" data-i18n="webshell.typeJsp">JSP</option>
                        <option value="custom" data-i18n="webshell.typeCustom">自定义</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="webshell-method" data-i18n="webshell.method">请求方式</label>
                    <select id="webshell-method">
                        <option value="post" data-i18n="webshell.methodPost">POST</option>
                        <option value="get" data-i18n="webshell.methodGet">GET</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="webshell-cmd-param" data-i18n="webshell.cmdParam">命令参数名</label>
                    <input type="text" id="webshell-cmd-param" data-i18n="webshell.cmdParamPlaceholder" data-i18n-attr="placeholder" placeholder="不填默认为 cmd，如 xxx 则请求为 xxx=命令" />
                </div>
                <div class="form-group">
                    <label for="webshell-os" data-i18n="webshell.os">目标系统</label>
                    <select id="webshell-os">
                        <option value="auto" data-i18n="webshell.osAuto">自动（按 Shell 类型推断）</option>
                        <option value="linux" data-i18n="webshell.osLinux">Linux / Unix</option>
                        <option value="windows" data-i18n="webshell.osWindows">Windows</option>
                    </select>
                    <small class="form-hint" data-i18n="webshell.osHint">决定文件管理/上传使用 Linux 还是 Windows 命令；PHP/JSP 跑在 Windows 上请选 Windows</small>
                </div>
                <div class="form-group">
                    <label for="webshell-encoding" data-i18n="webshell.encoding">响应编码</label>
                    <select id="webshell-encoding">
                        <option value="auto" data-i18n="webshell.encodingAuto">自动检测</option>
                        <option value="utf-8" data-i18n="webshell.encodingUtf8">UTF-8</option>
                        <option value="gbk" data-i18n="webshell.encodingGbk">GBK（中文 Windows）</option>
                        <option value="gb18030" data-i18n="webshell.encodingGb18030">GB18030</option>
                    </select>
                    <small class="form-hint" data-i18n="webshell.encodingHint">中文 Windows 目标若出现乱码，请切换为 GBK 或 GB18030</small>
                </div>
                <div class="form-group">
                    <label for="webshell-remark" data-i18n="webshell.remark">备注</label>
                    <input type="text" id="webshell-remark" data-i18n="webshell.remarkPlaceholder" data-i18n-attr="placeholder" placeholder="便于识别的备注名" />
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn-secondary" id="webshell-test-btn" onclick="testWebshellConnection()" data-i18n="webshell.testConnectivity">测试连通性</button>
                <button class="btn-secondary" onclick="closeWebshellModal()" data-i18n="common.cancel">取消</button>
                <button class="btn-primary" onclick="saveWebshellConnection()" data-i18n="common.save">保存</button>
            </div>
        </div>
    </div>

    <!-- 角色选择弹窗 -->
    <div id="role-select-modal" class="modal">
        <div class="modal-content role-select-modal-content">
            <div class="modal-header">
                <h2 data-i18n="chatGroup.rolePanelTitle">选择角色</h2>
                <span class="modal-close" onclick="closeRoleSelectModal()">&times;</span>
            </div>
            <div class="modal-body role-select-body">
                <div id="role-select-list" class="role-select-list"></div>
            </div>
        </div>
    </div>

    <!-- 角色编辑模态框 -->
    <div id="role-modal" class="modal">
        <div class="modal-content" style="max-width: 900px;">
            <div class="modal-header">
                <h2 id="role-modal-title" data-i18n="roleModal.addRole">添加角色</h2>
                <span class="modal-close" onclick="closeRoleModal()">&times;</span>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="role-name"><span data-i18n="roleModal.roleName">角色名称</span> <span style="color: red;">*</span></label>
                    <input type="text" id="role-name" data-i18n="roleModal.roleNamePlaceholder" data-i18n-attr="placeholder" placeholder="输入角色名称" required />
                </div>
                <div class="form-group">
                    <label for="role-description" data-i18n="roleModal.roleDescription">角色描述</label>
                    <input type="text" id="role-description" data-i18n="roleModal.roleDescriptionPlaceholder" data-i18n-attr="placeholder" placeholder="输入角色描述" />
                </div>
                <div class="form-group">
                    <label for="role-icon" data-i18n="roleModal.roleIcon">角色图标</label>
                    <input type="text" id="role-icon" data-i18n="roleModal.roleIconPlaceholder" data-i18n-attr="placeholder" placeholder="输入emoji图标，例如: 🏆" maxlength="10" />
                    <small class="form-hint" data-i18n="roleModal.roleIconHint">输入一个emoji作为角色的图标，将显示在角色选择器中。</small>
                </div>
                <div class="form-group">
                    <label for="role-user-prompt" data-i18n="roleModal.userPrompt">用户提示词</label>
                    <textarea id="role-user-prompt" rows="10" data-i18n="roleModal.userPromptPlaceholder" data-i18n-attr="placeholder" placeholder="输入用户提示词，会在用户消息前追加此提示词..."></textarea>
                    <small class="form-hint" data-i18n="roleModal.userPromptHint">此提示词会追加到用户消息前，用于指导AI的行为。注意：这不会修改系统提示词。</small>
                </div>
                <div class="form-group" id="role-tools-section">
                    <label data-i18n="roleModal.relatedTools">关联的工具（可选）</label>
                    <div id="role-tools-default-hint" class="role-tools-default-hint" style="display: none;">
                        <div class="role-tools-default-info">
                            <span class="role-tools-default-icon">ℹ️</span>
                            <div class="role-tools-default-content">
                                <div class="role-tools-default-title" data-i18n="roleModal.defaultRoleToolsTitle">默认角色使用所有工具</div>
                                <div class="role-tools-default-desc" data-i18n="roleModal.defaultRoleToolsDesc">默认角色会自动使用MCP管理中启用的所有工具，无需单独配置。</div>
                            </div>
                        </div>
                    </div>
                    <div class="role-tools-controls">
                        <div class="role-tools-actions">
                            <button type="button" class="btn-secondary" onclick="selectAllRoleTools()" data-i18n="roleModal.selectAll">全选</button>
                            <button type="button" class="btn-secondary" onclick="deselectAllRoleTools()" data-i18n="roleModal.deselectAll">全不选</button>
                            <div id="role-tools-status-filter" class="tools-status-filter">
                                <button type="button" class="btn-filter active" data-filter="" onclick="filterRoleToolsByStatus('')" data-i18n="roleModal.filterRoleAll">全部</button>
                                <button type="button" class="btn-filter" data-filter="role_on" onclick="filterRoleToolsByStatus('role_on')" data-i18n="roleModal.filterRoleOn">本角色已开</button>
                                <button type="button" class="btn-filter" data-filter="role_off" onclick="filterRoleToolsByStatus('role_off')" data-i18n="roleModal.filterRoleOff">本角色已关</button>
                            </div>
                            <div class="role-tools-search-box">
                                <input type="text" id="role-tools-search" data-i18n="roleModal.searchToolsPlaceholder" data-i18n-attr="placeholder" placeholder="搜索工具..." 
                                       oninput="searchRoleTools(this.value)" 
                                       onkeypress="if(event.key === 'Enter') searchRoleTools(this.value)" />
                                <button class="role-tools-search-clear" id="role-tools-search-clear" 
                                        onclick="clearRoleToolsSearch()" style="display: none;" data-i18n="common.clearSearch" data-i18n-attr="title" title="清除搜索">
                                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                        <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
                                        <path d="M15 9l-6 6M9 9l6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
                                    </svg>
                                </button>
                            </div>
                        </div>
                        <div id="role-tools-stats" class="role-tools-stats"></div>
                    </div>
                    <div id="role-tools-list" class="role-tools-list">
                        <div class="tools-loading" data-i18n="roleModal.loadingTools">正在加载工具列表...</div>
                    </div>
                    <small class="form-hint" data-i18n="roleModal.relatedToolsHint">勾选要关联的工具，留空则使用MCP管理中的全部工具配置。</small>
                </div>
                <div class="form-group">
                    <label class="checkbox-label">
                        <input type="checkbox" id="role-enabled" class="modern-checkbox" checked />
                        <span class="checkbox-custom"></span>
                        <span class="checkbox-text" data-i18n="roleModal.enableRole">启用此角色</span>
                    </label>
                </div>
            </div>
            <div class="modal-footer">
                <button class="btn-secondary" onclick="closeRoleModal()" data-i18n="common.cancel">取消</button>
                <button class="btn-primary" onclick="saveRole()" data-i18n="common.save">保存</button>
            </div>
        </div>
    </div>

    <!-- 项目管理弹窗（挂 body 下，避免被 .page overflow 裁剪） -->
    <div id="project-modal" class="modal-overlay projects-modal-overlay" style="display:none;" role="dialog" aria-modal="true" aria-labelledby="project-modal-title" onclick="if(event.target===this)closeProjectModal()">
        <div class="projects-modal-dialog" onclick="event.stopPropagation()">
            <div class="projects-modal-header">
                <div class="projects-modal-header-text">
                    <div>
                        <h3 id="project-modal-title" data-i18n="projects.modalNewTitle">新建项目</h3>
                        <p id="project-modal-subtitle" class="projects-modal-subtitle" data-i18n="projects.modalNewSubtitle">创建后可绑定对话，跨会话共享事实黑板</p>
                    </div>
                </div>
                <button type="button" class="projects-modal-close" onclick="closeProjectModal()" aria-label="关闭" data-i18n="common.close" data-i18n-attr="aria-label" data-i18n-skip-text="true">&times;</button>
            </div>
            <div class="projects-modal-body">
                <div class="projects-form-field">
                    <label for="project-modal-name" data-i18n="projects.projectName">项目名称 <span class="required">*</span></label>
                    <input type="text" id="project-modal-name" class="form-input" placeholder="例如：某客户 Web 渗透" autocomplete="off" data-i18n="projects.projectNamePlaceholder" data-i18n-attr="placeholder">
                </div>
                <div class="projects-form-field">
                    <label for="project-modal-description" data-i18n="projects.projectDescription">项目描述</label>
                    <textarea id="project-modal-description" class="form-input" rows="4" placeholder="测试范围、授权边界、注意事项…" data-i18n="projects.projectDescriptionPlaceholder" data-i18n-attr="placeholder"></textarea>
                </div>
            </div>
            <div class="projects-modal-footer">
                <button class="btn-secondary" type="button" onclick="closeProjectModal()" data-i18n="common.cancel">取消</button>
                <button class="btn-primary" type="button" id="project-modal-submit-btn" onclick="saveProjectModal()" data-i18n="projects.createProject">创建项目</button>
            </div>
        </div>
    </div>
    <div id="fact-modal" class="modal-overlay projects-modal-overlay" style="display:none;" role="dialog" aria-modal="true" onclick="if(event.target===this)closeFactModal()">
        <div class="projects-modal-dialog projects-modal-dialog--wide" onclick="event.stopPropagation()">
            <div class="projects-modal-header">
                <div class="projects-modal-header-text">
                    <div>
                        <h3 id="fact-modal-title" data-i18n="projects.addFact">添加事实</h3>
                        <p class="projects-modal-subtitle" data-i18n="projects.factModalSubtitle">摘要注入黑板索引；body 沉淀攻击链与 POC，供审计复现（与漏洞记录分工）</p>
                    </div>
                </div>
                <button type="button" class="projects-modal-close" onclick="closeFactModal()" aria-label="关闭" data-i18n="common.close" data-i18n-attr="aria-label" data-i18n-skip-text="true">&times;</button>
            </div>
            <div class="projects-modal-body">
                <div class="projects-form-field">
                    <label for="fact-modal-key">fact_key</label>
                    <input type="text" id="fact-modal-key" class="form-input" placeholder="target/primary_domain 或 finding/sqli-login" oninput="updateFactFormHints()">
                    <p class="projects-field-hint">环境类：target/、auth/、infra/、business/；发现/利用：finding/、chain/、exploit/、poc/</p>
                </div>
                <div class="projects-form-row">
                    <div class="projects-form-field">
                        <label for="fact-modal-category" data-i18n="projects.category">分类</label>
                        <select id="fact-modal-category" class="form-input" onchange="updateFactFormHints()">
                            <option value="target">target（目标）</option>
                            <option value="auth">auth（认证）</option>
                            <option value="infra">infra（基础设施）</option>
                            <option value="business">business（业务）</option>
                            <option value="finding">finding（发现）</option>
                            <option value="chain">chain（攻击链）</option>
                            <option value="exploit">exploit（利用）</option>
                            <option value="poc">poc（POC）</option>
                            <option value="note" selected>note（备注）</option>
                        </select>
                    </div>
                    <div class="projects-form-field">
                        <label for="fact-modal-confidence" data-i18n="projects.confidence">置信度</label>
                        <select id="fact-modal-confidence" class="form-input">
                            <option value="tentative">待确认</option>
                            <option value="confirmed">已确认</option>
                            <option value="deprecated">已废弃</option>
                        </select>
                    </div>
                </div>
                <div class="projects-form-field">
                    <label for="fact-modal-summary">摘要（索引一行）</label>
                    <input type="text" id="fact-modal-summary" class="form-input" maxlength="400" placeholder="什么 + 在哪 + 如何验证（勿仅写「存在 XSS」）" oninput="updateFactFormHints()">
                </div>
                <div class="projects-form-field">
                    <div class="projects-form-label-row">
                        <label for="fact-modal-body">body（可复现详情）</label>
                        <div class="projects-form-label-actions">
                            <button type="button" class="btn-link btn-small" onclick="insertFactBodyTemplate('attack')">插入攻击链模板</button>
                            <button type="button" class="btn-link btn-small" onclick="insertFactBodyTemplate('env')">插入环境模板</button>
                        </div>
                    </div>
                    <textarea id="fact-modal-body" class="form-input fact-modal-body-input" rows="14" placeholder="攻击链步骤、HTTP/命令 POC、响应现象、证据…" oninput="updateFactFormHints()"></textarea>
                    <p id="fact-modal-body-hint" class="projects-field-hint" role="status"></p>
                </div>
                <div class="projects-form-field">
                    <label for="fact-modal-related-vuln" data-i18n="projects.relatedVulnIdLabel">关联漏洞 ID</label>
                    <input type="text" id="fact-modal-related-vuln" class="form-input" placeholder="可选" data-i18n="projects.optional" data-i18n-attr="placeholder">
                </div>
            </div>
            <div class="projects-modal-footer">
                <button class="btn-secondary" type="button" onclick="closeFactModal()" data-i18n="common.cancel">取消</button>
                <button class="btn-primary" type="button" id="fact-modal-submit-btn" onclick="saveFactModal()" data-i18n="projects.saveFact">保存事实</button>
            </div>
        </div>
    </div>
    <div id="fact-detail-modal" class="modal-overlay projects-modal-overlay" style="display:none;" role="dialog" aria-modal="true" onclick="if(event.target===this)closeFactDetailModal()">
        <div class="projects-modal-dialog projects-modal-dialog--wide" onclick="event.stopPropagation()">
            <div class="projects-modal-header">
                <div class="projects-modal-header-text">
                    <div>
                        <h3 id="fact-detail-title" data-i18n="projects.factDetails">事实详情</h3>
                        <p id="fact-detail-meta" class="projects-modal-subtitle"></p>
                    </div>
                </div>
                <button type="button" class="projects-modal-close" onclick="closeFactDetailModal()" aria-label="关闭" data-i18n="common.close" data-i18n-attr="aria-label" data-i18n-skip-text="true">&times;</button>
            </div>
            <div class="projects-modal-body">
                <p id="fact-detail-sparse-warn" class="projects-fact-sparse-warn" hidden></p>
                <div id="fact-detail-prev-wrap" class="fact-detail-prev-wrap" hidden>
                    <h4 class="fact-detail-prev-title" data-i18n="projects.previousVersion">上一版本</h4>
                    <p id="fact-detail-prev-meta" class="projects-modal-subtitle"></p>
                    <pre id="fact-detail-prev-body" class="fact-detail-body fact-detail-body--muted"></pre>
                </div>
                <h4 class="fact-detail-current-title" data-i18n="projects.currentVersion">当前版本</h4>
                <pre id="fact-detail-body" class="fact-detail-body"></pre>
            </div>
            <div class="projects-modal-footer projects-modal-footer--split">
                <div class="projects-modal-footer-left">
                    <button class="btn-secondary btn-small" type="button" id="fact-detail-link-vuln-btn" onclick="linkFactToExistingVulnerability()" hidden data-i18n="projects.linkVulnerability">关联漏洞</button>
                    <button class="btn-secondary btn-small" type="button" id="fact-detail-create-vuln-btn" onclick="createVulnerabilityFromCurrentFact()" hidden data-i18n="projects.createVulnerabilityDraft">生成漏洞草稿</button>
                </div>
                <div class="projects-modal-footer-right">
                    <button class="btn-secondary" type="button" onclick="closeFactDetailModal()" data-i18n="common.close">关闭</button>
                    <button class="btn-primary" type="button" id="fact-detail-edit-btn" onclick="editFactFromDetail()" data-i18n="common.edit">编辑</button>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/i18next@23.11.5/i18next.min.js"></script>
    <script src="/static/js/i18n.js"></script>
    <script src="/static/js/builtin-tools.js"></script>
    <script src="/static/js/auth.js"></script>
    <script src="/static/js/notifications.js"></script>
    <script src="/static/js/info-collect.js"></script>
    <script src="/static/js/router.js"></script>
    <script src="/static/js/agents.js"></script>
    <script src="/static/js/dashboard.js"></script>
    <script src="/static/js/chat-scroll.js"></script>
    <script src="/static/js/monitor.js"></script>
    <script src="/static/js/chat.js"></script>
    <script src="/static/js/hitl.js"></script>
    <script src="/static/js/settings.js"></script>
    <script src="/static/js/audit.js"></script>
    <script src="/static/js/wechat-robot.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/xterm@4.19.0/lib/xterm.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.js"></script>
    <script src="/static/js/terminal.js"></script>
    <script src="/static/js/knowledge.js"></script>
    <script src="/static/js/skills.js"></script>
    <script src="/static/js/projects.js"></script>
    <script src="/static/js/vulnerability.js?v=12"></script>
    <script src="/static/js/webshell.js"></script>
    <script src="/static/js/chat-files.js"></script>
    <script src="/static/js/tasks.js"></script>
    <script src="/static/js/roles.js"></script>
    <script src="/static/js/c2.js"></script>
</body>
</html>

