// static/app-enhanced.js - 修复版，正确实现Token实时更新

function updateViewportHeightVar() {
    const docEl = document.documentElement;
    const visualViewport = window.visualViewport;

    if (visualViewport) {
        const vh = visualViewport.height;
        const bottomInset = Math.max(
            0,
            (window.innerHeight || docEl.clientHeight || vh) - visualViewport.height - visualViewport.offsetTop
        );
        docEl.style.setProperty('--app-viewport', `${vh}px`);
        docEl.style.setProperty('--app-bottom-inset', `${bottomInset}px`);
    } else {
        const height = window.innerHeight || docEl.clientHeight;
        if (height) {
            docEl.style.setProperty('--app-viewport', `${height}px`);
        }
        docEl.style.setProperty('--app-bottom-inset', 'env(safe-area-inset-bottom, 0px)');
    }
}

updateViewportHeightVar();
window.addEventListener('resize', updateViewportHeightVar);
window.addEventListener('orientationchange', updateViewportHeightVar);
window.addEventListener('pageshow', updateViewportHeightVar);
if (window.visualViewport) {
    window.visualViewport.addEventListener('resize', updateViewportHeightVar);
    window.visualViewport.addEventListener('scroll', updateViewportHeightVar);
}

const SOCKET_IO_CDN_SOURCES = [
    'https://cdn.socket.io/4.7.5/socket.io.min.js',
    'https://cdn.jsdelivr.net/npm/socket.io-client@4.7.5/dist/socket.io.min.js',
    'https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.5/socket.io.min.js'
];

function injectScriptSequentially(urls, onSuccess, onFailure) {
    let index = 0;
    const tryLoad = () => {
        if (index >= urls.length) {
            onFailure();
            return;
        }
        const url = urls[index];
        const script = document.createElement('script');
        script.src = url;
        script.async = false;
        script.onload = () => {
            if (typeof io !== 'undefined') {
                console.log(`Socket.IO 已从 ${url} 加载`);
                onSuccess();
            } else {
                index += 1;
                tryLoad();
            }
        };
        script.onerror = () => {
            console.warn(`无法从 ${url} 加载 Socket.IO，尝试下一个源`);
            index += 1;
            tryLoad();
        };
        document.head.appendChild(script);
    };
    tryLoad();
}

async function ensureSocketIOLoaded() {
    if (typeof io !== 'undefined') {
        return true;
    }
    return await new Promise((resolve) => {
        injectScriptSequentially(
            SOCKET_IO_CDN_SOURCES,
            () => resolve(true),
            () => resolve(false)
        );
    });
}

async function bootstrapApp() {
    // 检查必要的库是否加载
    if (typeof Vue === 'undefined') {
        console.error('错误：Vue.js 未加载');
        document.body.innerHTML = '<h1 style="color:red;">Vue.js 加载失败，请刷新页面</h1>';
        return;
    }
    
    if (typeof io === 'undefined') {
        const loaded = await ensureSocketIOLoaded();
        if (!loaded || typeof io === 'undefined') {
            console.error('错误：Socket.IO 未加载');
            document.body.innerHTML = '<h1 style="color:red;">Socket.IO 加载失败，请检查网络后刷新页面</h1>';
            return;
        }
    }
    
    console.log('所有依赖加载成功，初始化Vue应用...');
    
    const { createApp } = Vue;

    const urlParams = new URLSearchParams(window.location.search || '');
    const pathName = window.location.pathname || '';
    const plusRouteMatch = pathName.match(/\/?([^\/+]+)\+([^\/]+)/i);
    const slashRouteMatch = pathName.match(/sub_agent[_/](.+)$/i);

    let detectedVariant = window.APP_VARIANT || urlParams.get('variant') || null;
    let detectedTaskId = window.SUB_AGENT_TASK_ID || urlParams.get('task_id') || null;
    let detectedConversationId = window.SUB_AGENT_CONVERSATION_ID || urlParams.get('conversation_id') || null;

    if (!detectedVariant) {
        if (plusRouteMatch || slashRouteMatch) {
            detectedVariant = 'sub_agent';
        } else {
            detectedVariant = 'main';
        }
    }

    if (!detectedTaskId) {
        if (plusRouteMatch) {
            detectedTaskId = slashRouteMatch ? slashRouteMatch[1] : plusRouteMatch[2];
        } else if (slashRouteMatch) {
            detectedTaskId = slashRouteMatch[1];
        }
    }

    if (!detectedConversationId && plusRouteMatch) {
        detectedConversationId = plusRouteMatch[1];
    }

    const initialVariant = detectedVariant;
    const initialSubAgentTaskId = detectedTaskId;
    const initialSubAgentConversationId = detectedConversationId;
    
    const app = createApp({
        data() {
            return {
                // 子智能体模式
                variant: initialVariant,
                subAgentTaskId: initialSubAgentTaskId || '',
                subAgentConversationId: initialSubAgentConversationId
                    ? (initialSubAgentConversationId.startsWith('conv_') ? initialSubAgentConversationId : `conv_${initialSubAgentConversationId}`)
                    : null,
                subAgentTaskInfo: {
                    task_id: initialSubAgentTaskId || '',
                    agent_id: '',
                    summary: '',
                    status: '',
                    message: '',
                    workspace_dir: '',
                    references_dir: '',
                    deliverables_dir: '',
                    target_project_dir: '',
                    reference_manifest: [],
                    last_tool: ''
                },
                readonlyNoticeShown: false,
                // 连接状态
                isConnected: false,
                socket: null,
                
                // 系统信息
                projectPath: '',
                agentVersion: '',
                thinkingMode: '未知',
                
                // 消息相关
                messages: [],
                inputMessage: '',
                
                // 当前消息索引
                currentMessageIndex: -1,
                streamingMessage: false,
                
                // 停止功能状态
                stopRequested: false,
                terminating: false,

                // 路由相关
                initialRouteResolved: false,
                
                // 文件相关
                fileTree: [],
                focusedFiles: {},
                expandedFolders: {},

                // 展开状态管理
                expandedBlocks: new Set(),
                
                // 滚动控制
                userScrolling: false,
                autoScrollEnabled: true,
                scrollListenerAttached: false,
                scrollListenerRetryWarned: false,
                
                // 面板宽度控制
                leftWidth: 280,
                rightWidth: 420,
                rightCollapsed: true,
                isResizing: false,
                resizingPanel: null,
                minPanelWidth: 200,
                maxPanelWidth: 600,
                
                // 工具状态跟踪
                preparingTools: new Map(),
                activeTools: new Map(),
                toolActionIndex: new Map(),
                toolActionIndex: new Map(),
                toolStacks: new Map(),
                
                // ==========================================
                // 对话管理相关状态
                // ==========================================
                
                // 对话历史侧边栏
                sidebarCollapsed: true,  // 默认收起对话侧边栏
                panelMode: 'files', // files | todo | subAgents
                subAgents: [],
                subAgentPollTimer: null,
                conversations: [],
                conversationsLoading: false,
                hasMoreConversations: false,
                loadingMoreConversations: false,
                currentConversationId: null,
                currentConversationTitle: '当前对话',
                
                // 搜索功能
                searchQuery: '',
                searchTimer: null,
                
                // 分页
                conversationsOffset: 0,
                conversationsLimit: 20,
                
                // 对话压缩状态
                compressing: false,

                // 设置菜单状态
                settingsOpen: false,
                thinkingScrollLocks: new Map(),

                // 工具控制菜单
                toolMenuOpen: false,
                toolSettings: [],
                toolSettingsLoading: false,

                // 文件上传状态
                uploading: false,

                // TODO 列表
                todoList: null,
                todoEmoji: '🗒️',
                fileEmoji: '📁',
                todoDoneEmoji: '☑️',
                todoPendingEmoji: '⬜️',
                toolCategoryEmojis: {
                    network: '🌐',
                    file_edit: '📝',
                    read_focus: '🔍',
                    terminal_realtime: '🖥️',
                    terminal_command: '⌨️',
                    memory: '🧠',
                    todo: '🗒️',
                    sub_agent: '🤖'
                },

                // 右键菜单相关
                contextMenu: {
                    visible: false,
                    x: 0,
                    y: 0,
                    node: null
                },
                onDocumentClick: null,
                onWindowScroll: null,
                onKeydownListener: null
            }
        },
        
        async mounted() {
            console.log('Vue应用已挂载');
            document.addEventListener('click', this.handleClickOutsideSettings);
            document.addEventListener('click', this.handleClickOutsideToolMenu);
            window.addEventListener('popstate', this.handlePopState);

            this.onDocumentClick = (event) => {
                if (!this.contextMenu.visible) {
                    return;
                }
                if (event.target && event.target.closest && event.target.closest('.context-menu')) {
                    return;
                }
                this.hideContextMenu();
            };

            this.onWindowScroll = () => {
                if (this.contextMenu.visible) {
                    this.hideContextMenu();
                }
            };

            this.onKeydownListener = (event) => {
                if (event.key === 'Escape' && this.contextMenu.visible) {
                    this.hideContextMenu();
                }
            };

            document.addEventListener('click', this.onDocumentClick);
            window.addEventListener('scroll', this.onWindowScroll, true);
            document.addEventListener('keydown', this.onKeydownListener);

            if (this.isSubAgentView) {
                document.documentElement.classList.add('sub-agent-view');
                document.body.classList.add('sub-agent-view');
                await this.bootstrapSubAgentRoute();
                this.initSocket();
                this.initScrollListener();
                this.loadSubAgentInitialData();
                this.subAgentPollTimer = setInterval(() => {
                    this.fetchSubAgentTaskInfo(true);
                }, 4000);
            } else {
                await this.bootstrapRoute();
                this.initSocket();
                this.initScrollListener();
                setTimeout(() => {
                    this.loadInitialData();
                }, 500);
                this.fetchSubAgents();
                this.subAgentPollTimer = setInterval(() => {
                    if (this.panelMode === 'subAgents') {
                        this.fetchSubAgents();
                    }
                }, 5000);
            }
        },

        beforeUnmount() {
            document.removeEventListener('click', this.handleClickOutsideSettings);
            document.removeEventListener('click', this.handleClickOutsideToolMenu);
            window.removeEventListener('popstate', this.handlePopState);
            if (this.onDocumentClick) {
                document.removeEventListener('click', this.onDocumentClick);
                this.onDocumentClick = null;
            }
            if (this.onWindowScroll) {
                window.removeEventListener('scroll', this.onWindowScroll, true);
                this.onWindowScroll = null;
            }
            if (this.onKeydownListener) {
                document.removeEventListener('keydown', this.onKeydownListener);
                this.onKeydownListener = null;
            }
            if (this.subAgentPollTimer) {
                clearInterval(this.subAgentPollTimer);
                this.subAgentPollTimer = null;
            }
            if (this.isSubAgentView) {
                document.documentElement.classList.remove('sub-agent-view');
                document.body.classList.remove('sub-agent-view');
            }
        },

        computed: {
            isSubAgentView() {
                return this.variant === 'sub_agent';
            }
        },
        
        methods: {
            openGuiFileManager() {
                window.open('/file-manager', '_blank');
            },

            findMessageByAction(action) {
                if (!action) {
                    return null;
                }
                for (const message of this.messages) {
                    if (!message.actions) {
                        continue;
                    }
                    if (message.actions.includes(action)) {
                        return message;
                    }
                }
                return null;
            },

            async bootstrapSubAgentRoute() {
                if (!this.isSubAgentView) {
                    await this.bootstrapRoute();
                    return;
                }
                if (this.subAgentConversationId) {
                    this.currentConversationId = this.subAgentConversationId;
                    this.currentConversationTitle = this.subAgentTaskInfo.summary || '子智能体对话';
                    this.initialRouteResolved = true;
                    return;
                }
                if (!this.subAgentTaskId) {
                    this.initialRouteResolved = true;
                    return;
                }
                const info = await this.fetchSubAgentTaskInfo(true);
                if (info && info.sub_conversation_id) {
                    const convId = info.sub_conversation_id;
                    this.subAgentConversationId = convId;
                    this.currentConversationId = convId;
                    this.currentConversationTitle = info.summary || this.currentConversationTitle;
                }
                this.initialRouteResolved = true;
            },

            async loadSubAgentInitialData() {
                if (!this.isSubAgentView) {
                    this.loadInitialData();
                    return;
                }
                const info = await this.fetchSubAgentTaskInfo();
                await this.fetchSubAgentConversation();
                await this.fetchSubAgentFileTree();
                await this.fetchTodoList();
                if (!this.socket || !this.socket.connected) {
                    setTimeout(() => {
                        if (!this.socket || !this.socket.connected) {
                            console.warn('WebSocket尚未建立，启用只读回放模式。');
                            this.isConnected = true;
                            if (!this.readonlyNoticeShown) {
                                this.readonlyNoticeShown = true;
                                const status = (info && info.status) ? info.status : 'unknown';
                                this.addSystemMessage(`🔗 子智能体连接尚未建立，已进入只读模式（当前状态：${status}）。`);
                            }
                        }
                    }, 1200);
                }
            },

            async fetchSubAgentTaskInfo(silent = false) {
                if (!this.subAgentTaskId) {
                    return null;
                }
                try {
                    const resp = await fetch(`/tasks/${encodeURIComponent(this.subAgentTaskId)}`);
                    if (!resp.ok) {
                        let payload;
                        try {
                            payload = await resp.json();
                        } catch (err) {
                            payload = { error: await resp.text() };
                        }
                        if (resp.status === 404) {
                            const fallback = {
                                task_id: this.subAgentTaskId,
                                status: 'archived',
                                summary: this.currentConversationTitle || '',
                                message: payload && payload.message ? payload.message : '任务不存在'
                            };
                            this.subAgentTaskInfo = { ...this.subAgentTaskInfo, ...fallback };
                            return fallback;
                        }
                        throw new Error(payload && (payload.error || payload.message) ? (payload.error || payload.message) : '加载失败');
                    }
                    const data = await resp.json();
                    if (!data.success) {
                        throw new Error(data.error || '加载失败');
                    }
                    this.subAgentTaskInfo = {
                        ...this.subAgentTaskInfo,
                        ...data
                    };
                    if (data.task_id && data.task_id !== this.subAgentTaskId) {
                        this.subAgentTaskId = data.task_id;
                        if (this.socket && this.socket.connected) {
                            this.socket.emit('sub_agent_join', { task_id: data.task_id });
                        }
                    }
                    if (data.workspace_dir) {
                        this.projectPath = data.workspace_dir;
                    }
                    if (data.sub_conversation_id && !this.subAgentConversationId) {
                        const convId = data.sub_conversation_id;
                        this.subAgentConversationId = convId;
                        this.currentConversationId = convId;
                    }
                    if (!silent && data.summary) {
                        this.currentConversationTitle = data.summary;
                    }
                    return data;
                } catch (error) {
                    if (!silent) {
                        console.warn('获取子智能体任务信息失败:', error);
                    }
                    if (!this.isConnected) {
                        this.addSystemMessage(`⚠️ 无法获取子智能体任务信息：${error.message || error}`);
                    }
                    return null;
                }
            },

            async fetchSubAgentConversation() {
                if (!this.subAgentTaskId) {
                    return;
                }
                try {
                    const resp = await fetch(`/tasks/${encodeURIComponent(this.subAgentTaskId)}/conversation`);
                    if (!resp.ok) {
                        const fallbackHandled = await this.tryFetchArchivedConversation();
                        if (!fallbackHandled) {
                            throw new Error(await resp.text());
                        }
                        return;
                    }
                    const data = await resp.json();
                    if (!data.success) {
                        const fallbackHandled = await this.tryFetchArchivedConversation();
                        if (!fallbackHandled) {
                            throw new Error(data.error || '加载失败');
                        }
                        return;
                    }
                    if (data.conversation_id) {
                        this.currentConversationId = data.conversation_id;
                    }
                    const transformed = this.transformHistoryMessages(data.messages || []);
                    this.messages = transformed;
                    this.$nextTick(() => this.scrollToBottom(true));
                    if (!this.currentConversationTitle && this.subAgentTaskInfo.summary) {
                        this.currentConversationTitle = this.subAgentTaskInfo.summary;
                    }
                } catch (error) {
                    console.warn('加载子智能体对话失败:', error);
                    if (!this.isConnected) {
                        this.isConnected = true;
                    }
                    this.addSystemMessage(`⚠️ 加载子智能体对话失败：${error.message || error}`);
                }
            },
            
            async tryFetchArchivedConversation() {
                if (!this.currentConversationId) {
                    return false;
                }
                try {
                    const response = await fetch(`/sub_agent/conversations/${this.currentConversationId}`);
                    if (!response.ok) {
                        return false;
                    }
                    const payload = await response.json();
                    if (!payload.success) {
                        return false;
                    }
                    const transformed = this.transformHistoryMessages(payload.messages || []);
                    this.messages = transformed;
                    this.$nextTick(() => this.scrollToBottom(true));
                    return true;
                } catch (err) {
                    console.warn('加载归档子智能体对话失败:', err);
                    return false;
                }
            },

            async fetchSubAgentFileTree() {
                if (!this.isSubAgentView || !this.subAgentTaskId) {
                    return;
                }
                try {
                    const resp = await fetch(`/tasks/${encodeURIComponent(this.subAgentTaskId)}/files`);
                    if (!resp.ok) {
                        throw new Error(await resp.text());
                    }
                    const data = await resp.json();
                    if (data.success && data.data) {
                        this.updateFileTree(data.data);
                    } else {
                        console.warn('获取子智能体文件树失败:', data.error || data.message);
                    }
                } catch (error) {
                    console.warn('加载子智能体文件树失败:', error);
                }
            },

            async sendSubAgentMessage() {
                if (!this.subAgentTaskId || this.sending) {
                    return;
                }
                const text = (this.inputMessage || '').trim();
                if (!text) {
                    return;
                }
                const userMessage = {
                    role: 'user',
                    content: text,
                    metadata: {},
                    actions: [],
                    streamingText: '',
                    streamingThinking: '',
                    currentStreamingType: null,
                    timestamp: new Date().toISOString()
                };
                this.messages.push(userMessage);
                this.currentMessageIndex = -1;
                this.inputMessage = '';
                this.sending = true;
                this.autoScrollEnabled = true;
                this.scrollToBottom(true);
                try {
                    await fetch(`/tasks/${encodeURIComponent(this.subAgentTaskId)}/messages`, {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ message: text })
                    });
                } catch (error) {
                    console.warn('发送子智能体消息失败:', error);
                } finally {
                    this.sending = false;
                }
            },

            async stopSubAgentTask() {
                if (!this.subAgentTaskId || this.stopping) {
                    return;
                }
                this.stopping = true;
                this.stopRequested = true;
                try {
                    await fetch(`/tasks/${encodeURIComponent(this.subAgentTaskId)}/stop`, { method: 'POST' });
                } catch (error) {
                    console.warn('停止子智能体任务失败:', error);
                } finally {
                    this.stopping = false;
                    this.stopRequested = false;
                }
            },

            async terminateSubAgentTask() {
                if (!this.subAgentTaskId || this.terminating) {
                    return;
                }
                const shouldTerminate = window.confirm('确定要立即关闭子智能体吗？此操作无法撤销。');
                if (!shouldTerminate) {
                    return;
                }
                this.terminating = true;
                try {
                    const resp = await fetch(`/tasks/${encodeURIComponent(this.subAgentTaskId)}/terminate`, { method: 'POST' });
                    let data = null;
                    try {
                        data = await resp.json();
                    } catch (err) {
                        data = { success: false, error: await resp.text() };
                    }
                    if (!resp.ok || !data.success) {
                        const message = (data && (data.error || data.message)) || '关闭失败';
                        alert(`关闭子智能体失败：${message}`);
                        return;
                    }
                    this.addSystemMessage('🛑 子智能体已被手动关闭。');
                } catch (error) {
                    console.warn('关闭子智能体失败:', error);
                    alert(`关闭子智能体失败：${error.message || error}`);
                } finally {
                    this.terminating = false;
                }
            },

            formatPathDisplay(path) {
                if (!path) {
                    return '—';
                }
                return path.replace(this.projectPath, '.');
            },

            formatSubAgentStatus(status) {
                if (!status) return '未知';
                const map = {
                    running: '进行中',
                    pending: '等待中',
                    completed: '已完成',
                    failed: '失败',
                    timeout: '超时',
                    terminated: '已关闭'
                };
                return map[status] || status;
            },

            async bootstrapRoute() {
                if (this.isSubAgentView) {
                    await this.bootstrapSubAgentRoute();
                    return;
                }
                const path = window.location.pathname.replace(/^\/+/, '');
                if (!path || path === 'new') {
                    this.currentConversationId = null;
                    this.currentConversationTitle = '新对话';
                    this.initialRouteResolved = true;
                    return;
                }

                const convId = path.startsWith('conv_') ? path : `conv_${path}`;
                try {
                    const resp = await fetch(`/api/conversations/${convId}/load`, { method: 'PUT' });
                    const result = await resp.json();
                    if (result.success) {
                        this.currentConversationId = convId;
                        this.currentConversationTitle = result.title || '对话';
                        history.replaceState({ conversationId: convId }, '', `/${this.stripConversationPrefix(convId)}`);
                    } else {
                        history.replaceState({}, '', '/new');
                        this.currentConversationId = null;
                        this.currentConversationTitle = '新对话';
                    }
                } catch (error) {
                    console.warn('初始化路由失败:', error);
                    history.replaceState({}, '', '/new');
                    this.currentConversationId = null;
                    this.currentConversationTitle = '新对话';
                } finally {
                    this.initialRouteResolved = true;
                }
            },

            handlePopState(event) {
                const state = event.state || {};
                const convId = state.conversationId;
                if (!convId) {
                    this.currentConversationId = null;
                    this.currentConversationTitle = '新对话';
                    this.messages = [];
                    this.resetAllStates();
                    return;
            }
            this.loadConversation(convId);
            },

            stripConversationPrefix(conversationId) {
                if (!conversationId) return '';
                return conversationId.startsWith('conv_') ? conversationId.slice(5) : conversationId;
            },

            showContextMenu(payload) {
                if (!payload || !payload.node) {
                    return;
                }
                const { node, event } = payload;
                console.log('context menu', node.path, node.type);
                if (event && typeof event.preventDefault === 'function') {
                    event.preventDefault();
                }
                if (event && typeof event.stopPropagation === 'function') {
                    event.stopPropagation();
                }
                if (!node.path && node.path !== '') {
                    this.hideContextMenu();
                    return;
                }
                if (node.type !== 'file' && node.type !== 'folder') {
                    this.hideContextMenu();
                    return;
                }

                this.hideContextMenu();

                let x = (event && event.clientX) || 0;
                let y = (event && event.clientY) || 0;
                const menuWidth = 200;
                const menuHeight = 50;
                const viewportWidth = window.innerWidth;
                const viewportHeight = window.innerHeight;

                if (x + menuWidth > viewportWidth) {
                    x = viewportWidth - menuWidth - 8;
                }
                if (y + menuHeight > viewportHeight) {
                    y = viewportHeight - menuHeight - 8;
                }

                this.contextMenu.visible = true;
                this.contextMenu.x = Math.max(8, x);
                this.contextMenu.y = Math.max(8, y);
                this.contextMenu.node = node;
            },

            hideContextMenu() {
                if (!this.contextMenu.visible) {
                    return;
                }
                this.contextMenu.visible = false;
                this.contextMenu.node = null;
            },

            async downloadFile(path) {
                if (!path) {
                    this.hideContextMenu();
                    return;
                }
                const url = `/api/download/file?path=${encodeURIComponent(path)}`;
                const name = path.split('/').pop() || 'file';
                await this.downloadResource(url, name);
            },

            async downloadFolder(path) {
                if (!path) {
                    this.hideContextMenu();
                    return;
                }
                const url = `/api/download/folder?path=${encodeURIComponent(path)}`;
                const segments = path.split('/').filter(Boolean);
                const folderName = segments.length ? segments.pop() : 'folder';
                await this.downloadResource(url, `${folderName}.zip`);
            },

            async downloadResource(url, filename) {
                try {
                    const response = await fetch(url);
                    if (!response.ok) {
                        let message = response.statusText;
                        try {
                            const errorData = await response.json();
                            message = errorData.error || errorData.message || message;
                        } catch (err) {
                            message = await response.text();
                        }
                        alert(`下载失败: ${message}`);
                        return;
                    }

                    const blob = await response.blob();
                    const downloadName = filename || 'download';
                    const link = document.createElement('a');
                    const href = URL.createObjectURL(blob);
                    link.href = href;
                    link.download = downloadName;
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    URL.revokeObjectURL(href);
                } catch (error) {
                    console.error('下载失败:', error);
                    alert(`下载失败: ${error.message || error}`);
                } finally {
                    this.hideContextMenu();
                }
            },

            initScrollListener() {
                if (this.scrollListenerAttached) {
                    return;
                }
                const attach = () => {
                    const messagesArea = this.$refs.messagesArea;
                    if (!messagesArea) {
                        if (!this.scrollListenerRetryWarned) {
                            console.warn('消息区域未找到，等待渲染后重试');
                            this.scrollListenerRetryWarned = true;
                        }
                        setTimeout(attach, 200);
                        return;
                    }
                    this.scrollListenerRetryWarned = false;
                    this.scrollListenerAttached = true;
                    
                    let isProgrammaticScroll = false;
                    const bottomThreshold = 12;
                    
                    this._setScrollingFlag = (flag) => {
                        isProgrammaticScroll = !!flag;
                    };
                    
                    messagesArea.addEventListener('scroll', () => {
                        if (isProgrammaticScroll) {
                            return;
                        }
                        
                        const scrollTop = messagesArea.scrollTop;
                        const scrollHeight = messagesArea.scrollHeight;
                        const clientHeight = messagesArea.clientHeight;
                        const isAtBottom = scrollHeight - scrollTop - clientHeight < bottomThreshold;
                        
                        if (isAtBottom) {
                            this.userScrolling = false;
                            this.autoScrollEnabled = true;
                        } else {
                            this.userScrolling = true;
                            this.autoScrollEnabled = false;
                        }
                    });
                };
                this.$nextTick(attach);
            },
            
            initSocket() {
                try {
                    console.log('初始化WebSocket连接...');
                    
                    const usePollingOnly = window.location.hostname !== 'localhost' &&
                        window.location.hostname !== '127.0.0.1';
                    
                    this.socket = io('/', usePollingOnly ? {
                        transports: ['polling'],
                        upgrade: false
                    } : {
                        transports: ['websocket', 'polling']
                    });
                    
                    // 连接事件
                    this.socket.on('connect', () => {
                        this.isConnected = true;
                        this.readonlyNoticeShown = false;
                        console.log('WebSocket已连接');
                        if (this.isSubAgentView) {
                            if (this.subAgentTaskId) {
                                this.socket.emit('sub_agent_join', { task_id: this.subAgentTaskId });
                            }
                        } else {
                            this.resetAllStates();
                        }
                    });
                    
                    this.socket.on('disconnect', () => {
                        this.isConnected = false;
                        console.log('WebSocket已断开');
                        if (!this.isSubAgentView) {
                            this.resetAllStates();
                        }
                    });
                    
                    this.socket.on('connect_error', (error) => {
                        console.error('WebSocket连接错误:', error.message);
                    });
                    
            this.socket.on('todo_updated', (data) => {
                console.log('收到todo更新事件:', data);
                if (!this.isSubAgentView && data && data.conversation_id) {
                    this.currentConversationId = data.conversation_id;
                }
                if (this.isSubAgentView && data && data.conversation_id && this.subAgentConversationId && data.conversation_id !== this.subAgentConversationId) {
                    return;
                }
                this.todoList = data && data.todo_list ? data.todo_list : null;
            });
                    
                    // 系统就绪
                    if (!this.isSubAgentView) {
                        this.socket.on('system_ready', (data) => {
                            this.projectPath = data.project_path || '';
                            this.agentVersion = data.version || this.agentVersion;
                            this.thinkingMode = data.thinking_mode || '未知';
                            console.log('系统就绪:', data);
                            
                            // 系统就绪后立即加载对话列表
                            this.loadConversationsList();
                        });

                        this.socket.on('tool_settings_updated', (data) => {
                            console.log('收到工具设置更新:', data);
                            if (data && Array.isArray(data.categories)) {
                                this.applyToolSettingsSnapshot(data.categories);
                            }
                        });
                    }
                    
                    // ==========================================
                    // 对话管理相关Socket事件
                    // ==========================================
                    
                    // 监听对话变更事件
                    if (!this.isSubAgentView) {
                        this.socket.on('conversation_changed', (data) => {
                            console.log('对话已切换:', data);
                            this.currentConversationId = data.conversation_id;
                            this.currentConversationTitle = data.title || '';
                            
                            if (data.cleared) {
                                this.messages = [];
                                this.currentConversationId = null;
                                this.currentConversationTitle = '';
                                history.replaceState({}, '', '/new');
                            }
                            
                            this.loadConversationsList();
                            this.fetchTodoList();
                        });

                        this.socket.on('conversation_resolved', (data) => {
                            if (!data || !data.conversation_id) {
                                return;
                            }
                            const convId = data.conversation_id;
                            this.currentConversationId = convId;
                            if (data.title) {
                                this.currentConversationTitle = data.title;
                            }
                            const pathFragment = this.stripConversationPrefix(convId);
                            const currentPath = window.location.pathname.replace(/^\/+/, '');
                            if (data.created) {
                                history.pushState({ conversationId: convId }, '', `/${pathFragment}`);
                            } else if (currentPath !== pathFragment) {
                                history.replaceState({ conversationId: convId }, '', `/${pathFragment}`);
                            }
                        });
                    } else {
                        this.socket.on('sub_agent_status', (data) => {
                            if (data && data.task_id === this.subAgentTaskId) {
                                this.subAgentTaskInfo.status = data.status || this.subAgentTaskInfo.status;
                                if (data.reason) {
                                    this.subAgentTaskInfo.message = data.reason;
                                } else if (data.message) {
                                    this.subAgentTaskInfo.message = data.message;
                                }
                            }
                        });
                    }
                    
                    // 监听对话加载事件
                    this.socket.on('conversation_loaded', (data) => {
                        console.log('对话已加载:', data);
                        if (data.clear_ui) {
                            // 清理当前UI状态，准备显示历史内容
                            this.resetAllStates();
                        }
                        
                        // 延迟获取并显示历史对话内容
                        setTimeout(() => {
                            this.fetchAndDisplayHistory();
                        }, 300);
                        
                        // 延迟获取Token统计（累计+当前上下文）
                        setTimeout(() => {
                            this.fetchTodoList();
                        }, 500);
                    });
                    
                    // 监听对话列表更新事件
                    this.socket.on('conversation_list_update', (data) => {
                        console.log('对话列表已更新:', data);
                        // 刷新对话列表
                        this.loadConversationsList();
                    });
                    
                    // 监听状态更新事件
                    this.socket.on('status_update', (status) => {
                        // 更新系统状态信息
                        if (status.conversation && status.conversation.current_id) {
                            this.currentConversationId = status.conversation.current_id;
                        }
                    });
                    
                    // AI消息开始
                    this.socket.on('ai_message_start', () => {
                        console.log('AI消息开始');
                        this.cleanupStaleToolActions();
                        const newMessage = {
                            role: 'assistant',
                            actions: [],
                            streamingThinking: '',
                            streamingText: '',
                            currentStreamingType: null
                        };
                        this.messages.push(newMessage);
                        this.currentMessageIndex = this.messages.length - 1;
                        this.streamingMessage = true;
                        this.stopRequested = false;
                        this.autoScrollEnabled = true;
                        this.scrollToBottom();
                    });
                    
                    // 思考流开始
                    this.socket.on('thinking_start', () => {
                        console.log('思考开始');
                        if (this.currentMessageIndex >= 0) {
                            const msg = this.messages[this.currentMessageIndex];
                            msg.streamingThinking = '';
                            msg.currentStreamingType = 'thinking';
                            
                            const action = {
                                id: Date.now() + Math.random(),
                                type: 'thinking',
                                content: '',
                                streaming: true,
                                timestamp: Date.now()
                            };
                            msg.actions.push(action);
                            
                            const blockId = `${this.currentMessageIndex}-thinking-${msg.actions.length - 1}`;
                            action.blockId = blockId;
                            this.expandedBlocks.add(blockId);
                            this.autoScrollEnabled = true;
                            this.userScrolling = false;
                            this.scrollToBottom();
                            this.thinkingScrollLocks.set(blockId, true);
                            this.$forceUpdate();
                        }
                    });
                    
                    // 思考内容块
                    this.socket.on('thinking_chunk', (data) => {
                        if (this.currentMessageIndex >= 0) {
                            const msg = this.messages[this.currentMessageIndex];
                            msg.streamingThinking += data.content;
                            
                            const lastAction = msg.actions[msg.actions.length - 1];
                            if (lastAction && lastAction.type === 'thinking') {
                                lastAction.content += data.content;
                            }
                            this.$forceUpdate();
                            if (lastAction && lastAction.blockId) {
                                this.$nextTick(() => this.scrollThinkingToBottom(lastAction.blockId));
                            } else {
                                this.conditionalScrollToBottom();
                            }
                        }
                    });
                    
                    // 思考结束
                    this.socket.on('thinking_end', (data) => {
                        console.log('思考结束');
                        if (this.currentMessageIndex >= 0) {
                            const msg = this.messages[this.currentMessageIndex];
                            const lastAction = msg.actions[msg.actions.length - 1];
                            if (lastAction && lastAction.type === 'thinking') {
                                lastAction.streaming = false;
                                lastAction.content = data.full_content;
                                if (lastAction.blockId) {
                                    setTimeout(() => {
                                        this.expandedBlocks.delete(lastAction.blockId);
                                        this.$forceUpdate();
                                    }, 1000);
                                    this.$nextTick(() => this.scrollThinkingToBottom(lastAction.blockId));
                                }
                            }
                            msg.streamingThinking = '';
                            msg.currentStreamingType = null;
                            this.$forceUpdate();
                        }
                    });
                    
                    // 文本流开始
                    this.socket.on('text_start', () => {
                        console.log('文本开始');
                        if (this.currentMessageIndex >= 0) {
                            const msg = this.messages[this.currentMessageIndex];
                            msg.streamingText = '';
                            msg.currentStreamingType = 'text';
                            
                            const action = {
                                id: Date.now() + Math.random(),
                                type: 'text',
                                content: '',
                                streaming: true,
                                timestamp: Date.now()
                            };
                            msg.actions.push(action);
                            this.$forceUpdate();
                        }
                    });
                    
                    // 文本内容块
                    this.socket.on('text_chunk', (data) => {
                        if (this.currentMessageIndex >= 0) {
                            const msg = this.messages[this.currentMessageIndex];
                            msg.streamingText += data.content;
                            
                            const lastAction = msg.actions[msg.actions.length - 1];
                            if (lastAction && lastAction.type === 'text') {
                                lastAction.content += data.content;
                            }
                            this.$forceUpdate();
                            this.conditionalScrollToBottom();
                            
                            // 实时渲染LaTeX
                            this.renderLatexInRealtime();
                        }
                    });
                    
                    // 文本结束
                    this.socket.on('text_end', (data) => {
                        console.log('文本结束');
                        if (this.currentMessageIndex >= 0) {
                            const msg = this.messages[this.currentMessageIndex];
                            
                            // 查找当前流式文本的action
                            for (let i = msg.actions.length - 1; i >= 0; i--) {
                                const action = msg.actions[i];
                                if (action.type === 'text' && action.streaming) {
                                    action.streaming = false;
                                    action.content = data.full_content;
                                    console.log('文本action已更新为完成状态');
                                    break;
                                }
                            }
                            
                            msg.streamingText = '';
                            msg.currentStreamingType = null;
                            this.$forceUpdate();
                        }
                    });
                    
                    // 工具提示事件（可选）
                    this.socket.on('tool_hint', (data) => {
                        console.log('工具提示:', data.name);
                        // 可以在这里添加提示UI
                    });
                    
                    // 工具准备中事件 - 实时显示
                    this.socket.on('tool_preparing', (data) => {
                        console.log('工具准备中:', data.name);
                        const msg = this.ensureAssistantMessage();
                        if (!msg) {
                            return;
                        }
                        const action = {
                            id: data.id,
                            type: 'tool',
                            tool: {
                                id: data.id,
                                name: data.name,
                                arguments: {},
                                argumentSnapshot: null,
                                argumentLabel: '',
                                status: 'preparing',
                                result: null,
                                message: data.message || `准备调用 ${data.name}...`
                            },
                            timestamp: Date.now()
                        };
                        msg.actions.push(action);
                        this.preparingTools.set(data.id, action);
                        this.registerToolAction(action, data.id);
                        this.trackToolAction(data.name, action);
                        this.$forceUpdate();
                        this.conditionalScrollToBottom();
                    });
                    
                    // 工具状态更新事件 - 实时显示详细状态
                    this.socket.on('tool_status', (data) => {
                        console.log('工具状态:', data);
                        const target = this.findToolAction(data.id, data.preparing_id, data.execution_id);
                        if (target) {
                            target.tool.statusDetail = data.detail;
                            target.tool.statusType = data.status;
                            this.$forceUpdate();
                            return;
                        }
                        const fallbackAction = this.getLatestActiveToolAction(data.tool);
                        if (fallbackAction) {
                            fallbackAction.tool.statusDetail = data.detail;
                            fallbackAction.tool.statusType = data.status;
                            this.registerToolAction(fallbackAction, data.execution_id || data.id || data.preparing_id);
                            this.$forceUpdate();
                        }
                    });
                    
                    // 工具开始（从准备转为执行）
                    this.socket.on('tool_start', (data) => {
                        console.log('工具开始执行:', data.name);
                        let action = null;
                        if (data.preparing_id && this.preparingTools.has(data.preparing_id)) {
                            action = this.preparingTools.get(data.preparing_id);
                            this.preparingTools.delete(data.preparing_id);
                        } else {
                            action = this.findToolAction(data.id, data.preparing_id, data.execution_id);
                        }
                        if (!action) {
                            const msg = this.ensureAssistantMessage();
                            if (!msg) {
                                return;
                            }
                            action = {
                                id: data.id,
                                type: 'tool',
                                    tool: {
                                        id: data.id,
                                        name: data.name,
                                        arguments: {},
                                        argumentSnapshot: null,
                                        argumentLabel: '',
                                        status: 'running',
                                        result: null
                                    },
                                    timestamp: Date.now()
                                };
                            msg.actions.push(action);
                        }
                        action.tool.status = 'running';
                        action.tool.arguments = data.arguments;
                        action.tool.argumentSnapshot = this.cloneToolArguments(data.arguments);
                        action.tool.argumentLabel = this.buildToolLabel(action.tool.argumentSnapshot);
                        action.tool.message = null;
                        action.tool.id = data.id;
                        action.tool.executionId = data.id;
                        this.registerToolAction(action, data.id);
                        this.trackToolAction(data.name, action);
                        this.$forceUpdate();
                        this.conditionalScrollToBottom();
                    });
                    
                    // 更新action（工具完成）
                    this.socket.on('update_action', (data) => {
                        console.log('更新action:', data.id, 'status:', data.status);
                        let targetAction = this.findToolAction(data.id, data.preparing_id, data.execution_id);
                        if (!targetAction && data.preparing_id && this.preparingTools.has(data.preparing_id)) {
                            targetAction = this.preparingTools.get(data.preparing_id);
                        }
                        if (!targetAction) {
                            outer: for (const message of this.messages) {
                                if (!message.actions) continue;
                                for (const action of message.actions) {
                                    if (action.type !== 'tool') continue;
                                    const matchByExecution = action.tool.executionId && action.tool.executionId === data.id;
                                    const matchByToolId = action.tool.id === data.id;
                                    const matchByPreparingId = action.id === data.preparing_id;
                                    if (matchByExecution || matchByToolId || matchByPreparingId) {
                                        targetAction = action;
                                        break outer;
                                    }
                                }
                            }
                        }
                        if (targetAction) {
                            if (data.status) {
                                targetAction.tool.status = data.status;
                            }
                            if (data.result !== undefined) {
                                targetAction.tool.result = data.result;
                            }
                            if (data.message !== undefined) {
                                targetAction.tool.message = data.message;
                            }
                            if (data.awaiting_content) {
                                targetAction.tool.awaiting_content = true;
                            } else if (data.status === 'completed') {
                                targetAction.tool.awaiting_content = false;
                            }
                            if (!targetAction.tool.executionId && (data.execution_id || data.id)) {
                                targetAction.tool.executionId = data.execution_id || data.id;
                            }
                            if (data.arguments) {
                                targetAction.tool.arguments = data.arguments;
                                targetAction.tool.argumentSnapshot = this.cloneToolArguments(data.arguments);
                                targetAction.tool.argumentLabel = this.buildToolLabel(targetAction.tool.argumentSnapshot);
                            }
                            this.registerToolAction(targetAction, data.execution_id || data.id);
                            if (data.status && ["completed", "failed", "error"].includes(data.status) && !data.awaiting_content) {
                                this.unregisterToolAction(targetAction);
                                if (data.id) {
                                    this.preparingTools.delete(data.id);
                                }
                                if (data.preparing_id) {
                                    this.preparingTools.delete(data.preparing_id);
                                }
                            }
                            this.$forceUpdate();
                            this.conditionalScrollToBottom();
                        }
                        
                        // 关键修复：每个工具完成后都更新当前上下文Token
                    if (data.status === 'completed') {
                        setTimeout(() => {
                        }, 500);
                    }
                });
                    
                    this.socket.on('append_payload', (data) => {
                        console.log('收到append_payload事件:', data);
                        if (this.currentMessageIndex >= 0) {
                            const msg = this.messages[this.currentMessageIndex];
                            const action = {
                                id: `append-payload-${Date.now()}-${Math.random()}`,
                                type: 'append_payload',
                                append: {
                                    path: data.path || '未知文件',
                                    forced: !!data.forced,
                                    success: data.success === undefined ? true : !!data.success,
                                    lines: data.lines ?? null,
                                    bytes: data.bytes ?? null
                                },
                                timestamp: Date.now()
                            };
                            msg.actions.push(action);
                            this.$forceUpdate();
                            this.conditionalScrollToBottom();
                        }
                    });
                    
                    this.socket.on('modify_payload', (data) => {
                        console.log('收到modify_payload事件:', data);
                        if (this.currentMessageIndex >= 0) {
                            const msg = this.messages[this.currentMessageIndex];
                            const action = {
                                id: `modify-payload-${Date.now()}-${Math.random()}`,
                                type: 'modify_payload',
                                modify: {
                                    path: data.path || '未知文件',
                                    total: data.total ?? null,
                                    completed: data.completed || [],
                                    failed: data.failed || [],
                                    forced: !!data.forced
                                },
                                timestamp: Date.now()
                            };
                            msg.actions.push(action);
                            this.$forceUpdate();
                            this.conditionalScrollToBottom();
                        }
                    });
                    
                    // 停止请求确认
                    this.socket.on('stop_requested', (data) => {
                        console.log('停止请求已接收:', data.message);
                        // 可以显示提示信息
                    });
                    
                    // 任务停止
                    this.socket.on('task_stopped', (data) => {
                        console.log('任务已停止:', data.message);
                        this.resetAllStates();
                    });
                    
                    // 任务完成（重点：更新Token统计）
                    this.socket.on('task_complete', (data) => {
                        console.log('任务完成', data);
                        this.resetAllStates();
                        
                        // 任务完成后立即更新Token统计（关键修复）
                        if (this.currentConversationId) { 
                        }
                    });
                    
                    // 聚焦文件更新
                    this.socket.on('focused_files_update', (data) => {
                        this.focusedFiles = data || {};
                        // 聚焦文件变化时更新当前上下文Token（关键修复）
                        if (this.currentConversationId) {
                            setTimeout(() => {
                            }, 500);
                        }
                    });
                    
                    // 文件树更新
                    this.socket.on('file_tree_update', (data) => {
                        this.updateFileTree(data);
                        // 文件树变化时也可能影响上下文
                        if (this.currentConversationId) {
                            setTimeout(() => {
                            }, 500);
                        }
                    });
                    
                    // 系统消息
                    this.socket.on('system_message', (data) => {
                        if (!data || !data.content) {
                            return;
                        }
                        this.appendSystemAction(data.content);
                    });
                    
                    // 错误处理
                    this.socket.on('error', (data) => {
                        this.addSystemMessage(`错误: ${data.message}`);
                        // 仅标记当前流结束，避免状态错乱
                        this.streamingMessage = false;
                        this.stopRequested = false;
                    });
                    
                    // 命令结果
                    this.socket.on('command_result', (data) => {
                        if (data.command === 'clear' && data.success) {
                            this.messages = [];
                            this.currentMessageIndex = -1;
                            this.expandedBlocks.clear();
                        } else if (data.command === 'status' && data.success) {
                            this.addSystemMessage(`系统状态:\n${JSON.stringify(data.data, null, 2)}`);
                        } else if (!data.success) {
                            this.addSystemMessage(`命令失败: ${data.message}`);
                        }
                    });
                    
                } catch (error) {
                    console.error('Socket初始化失败:', error);
                }
            },

            registerToolAction(action, executionId = null) {
                if (!action || action.type !== 'tool') {
                    return;
                }
                const keys = new Set();
                if (action.id) {
                    keys.add(action.id);
                }
                if (action.tool && action.tool.id) {
                    keys.add(action.tool.id);
                }
                if (executionId) {
                    keys.add(executionId);
                }
                if (action.tool && action.tool.executionId) {
                    keys.add(action.tool.executionId);
                }
                keys.forEach(key => {
                    if (!key) {
                        return;
                    }
                    this.toolActionIndex.set(key, action);
                });
            },

            unregisterToolAction(action) {
                if (!action || action.type !== 'tool') {
                    return;
                }
                const keysToRemove = [];
                for (const [key, stored] of this.toolActionIndex.entries()) {
                    if (stored === action) {
                        keysToRemove.push(key);
                    }
                }
                keysToRemove.forEach(key => this.toolActionIndex.delete(key));
                if (action.tool && action.tool.name) {
                    this.releaseToolAction(action.tool.name, action);
                }
            },

            findToolAction(id, preparingId, executionId) {
                if (!this.toolActionIndex) {
                    return null;
                }
                const candidates = [executionId, id, preparingId];
                for (const key of candidates) {
                    if (key && this.toolActionIndex.has(key)) {
                        return this.toolActionIndex.get(key);
                    }
                }
                return null;
            },

            trackToolAction(toolName, action) {
                if (!toolName || !action) {
                    return;
                }
                if (!this.toolStacks.has(toolName)) {
                    this.toolStacks.set(toolName, []);
                }
                const stack = this.toolStacks.get(toolName);
                if (!stack.includes(action)) {
                    stack.push(action);
                }
            },

            releaseToolAction(toolName, action) {
                if (!toolName || !this.toolStacks.has(toolName)) {
                    return;
                }
                const stack = this.toolStacks.get(toolName);
                const index = stack.indexOf(action);
                if (index !== -1) {
                    stack.splice(index, 1);
                }
                if (stack.length === 0) {
                    this.toolStacks.delete(toolName);
                }
            },

            getLatestActiveToolAction(toolName) {
                if (!toolName || !this.toolStacks.has(toolName)) {
                    return null;
                }
                const stack = this.toolStacks.get(toolName);
                for (let i = stack.length - 1; i >= 0; i--) {
                    const action = stack[i];
                    if (!action || action.type !== 'tool' || !action.tool) {
                        continue;
                    }
                    if (['preparing', 'running', 'stale'].includes(action.tool.status)) {
                        return action;
                    }
                }
                return stack[stack.length - 1] || null;
            },

            cleanupStaleToolActions() {
                this.messages.forEach(msg => {
                    if (!msg.actions) {
                        return;
                    }
                    msg.actions.forEach(action => {
                        if (action.type !== 'tool' || !action.tool) {
                            return;
                        }
                        if (['running', 'preparing'].includes(action.tool.status)) {
                            action.tool.status = 'stale';
                            action.tool.message = action.tool.message || '已被新的响应中断';
                            this.unregisterToolAction(action);
                        }
                    });
                });
                this.preparingTools.clear();
                this.toolActionIndex.clear();
            },

            ensureAssistantMessage() {
                if (this.currentMessageIndex >= 0) {
                    return this.messages[this.currentMessageIndex];
                }
                const message = {
                    role: 'assistant',
                    actions: [],
                    streamingThinking: '',
                    streamingText: '',
                    currentStreamingType: null
                };
                this.messages.push(message);
                this.currentMessageIndex = this.messages.length - 1;
                return message;
            },
            
            // 完整重置所有状态
            resetAllStates() {
                console.log('重置所有前端状态');
                this.hideContextMenu();
                
                // 重置消息和流状态
                this.streamingMessage = false;
                this.currentMessageIndex = -1;
                this.stopRequested = false;
                
                // 清理工具状态
                this.preparingTools.clear();
                this.activeTools.clear();
                this.toolActionIndex.clear();
                
                // ✨ 新增：将所有未完成的工具标记为已完成
                this.messages.forEach(msg => {
                    if (msg.role === 'assistant' && msg.actions) {
                        msg.actions.forEach(action => {
                            if (action.type === 'tool' && 
                                (action.tool.status === 'preparing' || action.tool.status === 'running')) {
                                action.tool.status = 'completed';
                            }
                        });
                    }
                });
                
                // 重置滚动状态
                this.userScrolling = false;
                this.autoScrollEnabled = true;
                
                // 清理Markdown缓存
                if (this.markdownCache) {
                    this.markdownCache.clear();
                }
                this.thinkingScrollLocks.clear();
                
                // 强制更新视图
                this.$forceUpdate();
                
                this.settingsOpen = false;
                this.toolMenuOpen = false;
                this.toolSettingsLoading = false;
                this.toolSettings = [];
                
                console.log('前端状态重置完成');
            },
            
            async loadInitialData() {
                if (this.isSubAgentView) {
                    await this.loadSubAgentInitialData();
                    return;
                }
                try {
                    console.log('加载初始数据...');
                    
                    const filesResponse = await fetch('/api/files');
                    const filesData = await filesResponse.json();
                    this.updateFileTree(filesData);
                    
                    const focusedResponse = await fetch('/api/focused');
                    const focusedData = await focusedResponse.json();
                    this.focusedFiles = focusedData || {};
                    
                    await this.fetchTodoList();
                    
                    const statusResponse = await fetch('/api/status');
                    const statusData = await statusResponse.json();
                    this.projectPath = statusData.project_path || '';
                    this.agentVersion = statusData.version || this.agentVersion;
                    this.thinkingMode = statusData.thinking_mode || '未知';
                    
                    // 获取当前对话信息
                    const statusConversationId = statusData.conversation && statusData.conversation.current_id;
                    if (statusConversationId) {
                        if (!this.currentConversationId) {
                            this.currentConversationId = statusConversationId;
                        }
                        // 如果有当前对话，尝试获取标题和Token统计
                        try {
                            const convResponse = await fetch(`/api/conversations/current`);
                            const convData = await convResponse.json();
                            if (convData.success && convData.data) {
                                this.currentConversationTitle = convData.data.title;
                            }
                            await this.fetchAndDisplayHistory();
                            // 获取当前对话的Token统计
                        } catch (e) {
                            console.warn('获取当前对话标题失败:', e);
                        }
                    }
                    
                    await this.loadToolSettings(true);
                    
                    console.log('初始数据加载完成');
                } catch (error) {
                    console.error('加载初始数据失败:', error);
                }
            },

            async refreshFileTree() {
                try {
                    const response = await fetch('/api/files');
                    const data = await response.json();
                    this.updateFileTree(data);
                } catch (error) {
                    console.error('刷新文件树失败:', error);
                }
            },
            
            // ==========================================
            // 对话管理核心功能
            // ==========================================
            
            async loadConversationsList() {
                this.conversationsLoading = true;
                try {
                    const response = await fetch(`/api/conversations?limit=${this.conversationsLimit}&offset=${this.conversationsOffset}`);
                    const data = await response.json();
                    
                    if (data.success) {
                        if (this.conversationsOffset === 0) {
                            this.conversations = data.data.conversations;
                        } else {
                            this.conversations.push(...data.data.conversations);
                        }
                        this.hasMoreConversations = data.data.has_more;
                        console.log(`已加载 ${this.conversations.length} 个对话`);

                        if (this.conversationsOffset === 0 && !this.currentConversationId && this.conversations.length > 0) {
                            const latestConversation = this.conversations[0];
                            if (latestConversation && latestConversation.id) {
                                await this.loadConversation(latestConversation.id);
                            }
                        }
                    } else {
                        console.error('加载对话列表失败:', data.error);
                    }
                } catch (error) {
                    console.error('加载对话列表异常:', error);
                } finally {
                    this.conversationsLoading = false;
                }
            },
            
            async loadMoreConversations() {
                if (this.loadingMoreConversations || !this.hasMoreConversations) return;
                
                this.loadingMoreConversations = true;
                this.conversationsOffset += this.conversationsLimit;
                await this.loadConversationsList();
                this.loadingMoreConversations = false;
            },
            
            async loadConversation(conversationId) {
                console.log('加载对话:', conversationId);
                
                if (conversationId === this.currentConversationId) {
                    console.log('已是当前对话，跳过加载');
                    return;
                }
                
                try {
                    // 1. 调用加载API
                    const response = await fetch(`/api/conversations/${conversationId}/load`, {
                        method: 'PUT'
                    });
                    const result = await response.json();
                    
                    if (result.success) {
                        console.log('对话加载API成功:', result);
                        
                        // 2. 更新当前对话信息
                        this.currentConversationId = conversationId;
                        this.currentConversationTitle = result.title;
                        history.pushState({ conversationId }, '', `/${this.stripConversationPrefix(conversationId)}`);
                        
                        // 3. 重置UI状态
                        this.resetAllStates();
                        
                        // 4. 延迟获取并显示历史对话内容（关键功能）
                        setTimeout(() => {
                            this.fetchAndDisplayHistory();
                        }, 300);
                        
                        // 5. 获取Token统计（重点：加载历史累计统计+当前上下文）
                        setTimeout(() => {
                        }, 500);
                        
                    } else {
                        console.error('对话加载失败:', result.message);
                        alert(`加载对话失败: ${result.message}`);
                    }
                } catch (error) {
                    console.error('加载对话异常:', error);
                    alert(`加载对话异常: ${error.message}`);
                }
            },
            
            // ==========================================
            // 关键功能：获取并显示历史对话内容
            // ==========================================
            async fetchAndDisplayHistory() {
                console.log('开始获取历史对话内容...');
                if (!this.currentConversationId || this.currentConversationId.startsWith('temp_')) {
                    console.log('没有当前对话ID，跳过历史加载');
                    return;
                }
                try {
                    const response = await fetch(`/api/conversations/${this.currentConversationId}/messages`);
                    if (!response.ok) {
                        console.warn('无法获取消息历史，尝试备用方法');
                        const statusResponse = await fetch('/api/status');
                        const status = await statusResponse.json();
                        if (status.conversation_history && Array.isArray(status.conversation_history)) {
                            this.renderHistoryMessages(status.conversation_history);
                        }
                        return;
                    }
                    const payload = await response.json();
                    if (payload.success && payload.data && Array.isArray(payload.data.messages)) {
                        this.renderHistoryMessages(payload.data.messages);
                    } else {
                        console.warn('历史消息结构异常:', payload);
                        this.messages = [];
                    }
                } catch (error) {
                    console.error('获取历史对话失败:', error);
                    this.messages = [];
                }
            },

            renderHistoryMessages(historyMessages) {
                const transformed = this.transformHistoryMessages(historyMessages);
                this.messages = transformed;
                this.$forceUpdate();
                this.$nextTick(() => this.scrollToBottom());
            },

            transformHistoryMessages(historyMessages = []) {
                if (!Array.isArray(historyMessages)) {
                    return [];
                }
                const output = [];
                let currentAssistantMessage = null;

                const flushAssistant = () => {
                    if (currentAssistantMessage && currentAssistantMessage.actions.length > 0) {
                        output.push(currentAssistantMessage);
                    }
                    currentAssistantMessage = null;
                };

                const ensureAssistantMessage = () => {
                    if (!currentAssistantMessage) {
                        currentAssistantMessage = {
                            role: 'assistant',
                            actions: [],
                            streamingThinking: '',
                            streamingText: '',
                            currentStreamingType: null
                        };
                    }
                    return currentAssistantMessage;
                };

                const parseToolArguments = (toolCall) => {
                    if (!toolCall || !toolCall.function) {
                        return {};
                    }
                    const raw = toolCall.function.arguments;
                    if (!raw) {
                        return {};
                    }
                    try {
                        return typeof raw === 'string' ? JSON.parse(raw || '{}') : raw;
                    } catch (error) {
                        console.warn('解析工具参数失败:', error);
                        return {};
                    }
                };

                const attachToolResult = (message, assistantMsg) => {
                    if (!assistantMsg || !assistantMsg.actions) {
                        return false;
                    }
                    const actions = assistantMsg.actions;
                    let toolAction = null;
                    if (message.tool_call_id) {
                        toolAction = actions.find(action => action.type === 'tool' && action.tool.id === message.tool_call_id);
                    }
                    if (!toolAction && message.name) {
                        const candidates = actions.filter(action => action.type === 'tool' && action.tool.name === message.name);
                        toolAction = candidates[candidates.length - 1];
                    }
                    if (!toolAction) {
                        return false;
                    }
                    let resultObj;
                    try {
                        resultObj = JSON.parse(message.content);
                    } catch (_) {
                        resultObj = message.content ? { output: message.content } : {};
                    }
                    toolAction.tool.status = resultObj.success === false ? 'failed' : 'completed';
                    toolAction.tool.result = resultObj;
                    if (message.name === 'append_to_file' && resultObj && typeof resultObj === 'object') {
                        const summary = {
                            path: resultObj.path || '未知文件',
                            success: resultObj.success !== false,
                            summary: resultObj.message || (resultObj.success === false ? '追加失败' : '追加完成'),
                            lines: resultObj.lines || 0,
                            bytes: resultObj.bytes || 0,
                            forced: !!resultObj.forced
                        };
                        assistantMsg.actions.push({
                            id: `history-append-${Date.now()}-${Math.random()}`,
                            type: 'append',
                            append: summary,
                            timestamp: Date.now()
                        });
                    }
                    return true;
                };

                const isToolResultNotice = (message) => {
                    if (!message || typeof message.content !== 'string') {
                        return false;
                    }
                    return message.content.trim().startsWith('[工具结果]');
                };

                const applyToolResultNotice = (message, assistantMsg) => {
                    if (!isToolResultNotice(message) || !assistantMsg) {
                        return false;
                    }
                    const trimmed = message.content.trim();
                    const headerMatch = trimmed.match(/\[工具结果\]\s*([^\s(]+)(?:\s*\(tool_call_id=([^)]+)\))?/);
                    const remainder = headerMatch ? trimmed.slice(headerMatch[0].length).trim() : '';
                    const synthetic = {
                        name: headerMatch ? headerMatch[1] : message.name,
                        tool_call_id: message.tool_call_id || (headerMatch ? headerMatch[2] : undefined),
                        content: remainder || '{}'
                    };
                    return attachToolResult(synthetic, assistantMsg);
                };

                historyMessages.forEach((message) => {
                    const role = (message.role || 'assistant').toLowerCase();
                    if (role === 'user') {
                        flushAssistant();
                        output.push({
                            role: 'user',
                            content: message.content || '',
                            metadata: message.metadata || {},
                            timestamp: message.timestamp
                        });
                        return;
                    }

                    if (role === 'assistant') {
                        const assistant = ensureAssistantMessage();
                        const content = message.content || '';
                        const metadata = message.metadata || {};
                        const appendPayloadMeta = metadata.append_payload;
                        const modifyPayloadMeta = metadata.modify_payload;

                        const thinkPatterns = [/<think>([\s\S]*?)<\/think>/g, /<thinking>([\s\S]*?)<\/thinking>/g];
                        let allThinkingContent = '';
                        for (const pattern of thinkPatterns) {
                            let match;
                            while ((match = pattern.exec(content)) !== null) {
                                allThinkingContent += match[1].trim() + '\n';
                            }
                        }
                        if (allThinkingContent.trim()) {
                            assistant.actions.push({
                                id: `history-think-${Date.now()}-${Math.random()}`,
                                type: 'thinking',
                                content: allThinkingContent.trim(),
                                streaming: false,
                                timestamp: Date.now()
                            });
                        }

                        let textContent = content
                            .replace(/<think>[\s\S]*?<\/think>/g, '')
                            .replace(/<thinking>[\s\S]*?<\/thinking>/g, '')
                            .trim();

                        if (appendPayloadMeta) {
                            assistant.actions.push({
                                id: `history-append-payload-${Date.now()}-${Math.random()}`,
                                type: 'append_payload',
                                append: {
                                    path: appendPayloadMeta.path || '未知文件',
                                    forced: !!appendPayloadMeta.forced,
                                    success: appendPayloadMeta.success === undefined ? true : !!appendPayloadMeta.success,
                                    lines: appendPayloadMeta.lines ?? null,
                                    bytes: appendPayloadMeta.bytes ?? null
                                },
                                timestamp: Date.now()
                            });
                        } else if (modifyPayloadMeta) {
                            assistant.actions.push({
                                id: `history-modify-payload-${Date.now()}-${Math.random()}`,
                                type: 'modify_payload',
                                modify: {
                                    path: modifyPayloadMeta.path || '未知文件',
                                    total: modifyPayloadMeta.total_blocks ?? null,
                                    completed: modifyPayloadMeta.completed || [],
                                    failed: modifyPayloadMeta.failed || [],
                                    forced: !!modifyPayloadMeta.forced,
                                    details: modifyPayloadMeta.details || []
                                },
                                timestamp: Date.now()
                            });
                        }

                        if (textContent && !appendPayloadMeta && !modifyPayloadMeta) {
                            assistant.actions.push({
                                id: `history-text-${Date.now()}-${Math.random()}`,
                                type: 'text',
                                content: textContent,
                                streaming: false,
                                timestamp: Date.now()
                            });
                        }

                        if (message.tool_calls && Array.isArray(message.tool_calls)) {
                            message.tool_calls.forEach((toolCall, tcIndex) => {
                                assistant.actions.push({
                                    id: `history-tool-${toolCall.id || Date.now()}-${tcIndex}`,
                                    type: 'tool',
                                    tool: {
                                        id: toolCall.id,
                                        name: toolCall.function?.name,
                                        arguments: parseToolArguments(toolCall),
                                        status: 'preparing',
                                        result: null
                                    },
                                    timestamp: Date.now()
                                });
                            });
                        }
                        return;
                    }

                    if (role === 'tool') {
                        if (!attachToolResult(message, currentAssistantMessage)) {
                            flushAssistant();
                            output.push({
                                role: 'system',
                                content: message.content || '',
                                metadata: message.metadata || {},
                                timestamp: message.timestamp
                            });
                        }
                        return;
                    }

                    if (applyToolResultNotice(message, currentAssistantMessage)) {
                        return;
                    }

                    flushAssistant();
                    output.push({
                        role: message.role || 'system',
                        content: message.content || '',
                        metadata: message.metadata || {},
                        timestamp: message.timestamp
                    });
                });

                flushAssistant();
                return output;
            },
            async createNewConversation() {
                console.log('创建新对话...');
                
                try {
                    const response = await fetch('/api/conversations', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({
                            thinking_mode: this.thinkingMode !== '快速模式'
                        })
                    });
                    
                    const result = await response.json();
                    
                    if (result.success) {
                        console.log('新对话创建成功:', result.conversation_id);
                        
                        // 清空当前消息
                        this.messages = [];
                        this.currentConversationId = result.conversation_id;
                        this.currentConversationTitle = '新对话';
                        history.pushState({ conversationId: this.currentConversationId }, '', `/${this.stripConversationPrefix(this.currentConversationId)}`);
                        
                        // 重置状态
                        this.resetAllStates();
                        
                        // 刷新对话列表
                        this.conversationsOffset = 0;
                        await this.loadConversationsList();
                        
                    } else {
                        console.error('创建对话失败:', result.message);
                        alert(`创建对话失败: ${result.message}`);
                    }
                } catch (error) {
                    console.error('创建对话异常:', error);
                    alert(`创建对话异常: ${error.message}`);
                }
            },
            
            async deleteConversation(conversationId) {
                if (!confirm('确定要删除这个对话吗？删除后无法恢复。')) {
                    return;
                }
                
                console.log('删除对话:', conversationId);
                
                try {
                    const response = await fetch(`/api/conversations/${conversationId}`, {
                        method: 'DELETE'
                    });
                    
                    const result = await response.json();
                    
                    if (result.success) {
                        console.log('对话删除成功');
                        
                        // 如果删除的是当前对话，清空界面
                        if (conversationId === this.currentConversationId) {
                            this.messages = [];
                            this.currentConversationId = null;
                            this.currentConversationTitle = '';
                            this.resetAllStates();
                            history.replaceState({}, '', '/new');
                        }
                        
                        // 刷新对话列表
                        this.conversationsOffset = 0;
                        await this.loadConversationsList();
                        
                    } else {
                        console.error('删除对话失败:', result.message);
                        alert(`删除对话失败: ${result.message}`);
                    }
                } catch (error) {
                    console.error('删除对话异常:', error);
                    alert(`删除对话异常: ${error.message}`);
                }
            },

            async duplicateConversation(conversationId) {
                console.log('复制对话:', conversationId);
                try {
                    const response = await fetch(`/api/conversations/${conversationId}/duplicate`, {
                        method: 'POST'
                    });

                    const result = await response.json();

                    if (response.ok && result.success) {
                        const newId = result.duplicate_conversation_id;
                        if (newId) {
                            this.currentConversationId = newId;
                        }

                        this.conversationsOffset = 0;
                        await this.loadConversationsList();
                    } else {
                        const message = result.message || result.error || '复制失败';
                        alert(`复制失败: ${message}`);
                    }
                } catch (error) {
                    console.error('复制对话异常:', error);
                    alert(`复制对话异常: ${error.message}`);
                }
            },
            
            searchConversations() {
                // 简单的搜索功能，实际实现可以调用搜索API
                if (this.searchTimer) {
                    clearTimeout(this.searchTimer);
                }
                
                this.searchTimer = setTimeout(() => {
                    if (this.searchQuery.trim()) {
                        console.log('搜索对话:', this.searchQuery);
                        // TODO: 实现搜索API调用
                        // this.searchConversationsAPI(this.searchQuery);
                    } else {
                        // 清空搜索，重新加载全部对话
                        this.conversationsOffset = 0;
                        this.loadConversationsList();
                    }
                }, 300);
            },
            
            toggleSidebar() {
                this.sidebarCollapsed = !this.sidebarCollapsed;
            },
            
            formatTime(timeString) {
                if (!timeString) return '';
                
                const date = new Date(timeString);
                const now = new Date();
                const diffMs = now - date;
                const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
                const diffDays = Math.floor(diffHours / 24);
                
                if (diffHours < 1) {
                    return '刚刚';
                } else if (diffHours < 24) {
                    return `${diffHours}小时前`;
                } else if (diffDays < 7) {
                    return `${diffDays}天前`;
                } else {
                    return date.toLocaleDateString('zh-CN', { 
                        month: 'short', 
                        day: 'numeric' 
                    });
                }
            },
            
            // ==========================================
            // 原有功能保持不变
            // ==========================================
            
            updateFileTree(structure) {
                const treeDictionary = structure && structure.tree ? structure.tree : {};

                const buildNodes = (treeMap) => {
                    if (!treeMap) {
                        return [];
                    }

                    const entries = Object.keys(treeMap).map((name) => {
                        const node = treeMap[name] || {};
                        if (node.type === 'folder') {
                            return {
                                type: 'folder',
                                name,
                                path: node.path || name,
                                children: buildNodes(node.children)
                            };
                        }
                        return {
                            type: 'file',
                            name,
                            path: node.path || name,
                            annotation: node.annotation || ''
                        };
                    });

                    entries.sort((a, b) => {
                        if (a.type !== b.type) {
                            return a.type === 'folder' ? -1 : 1;
                        }
                        return a.name.localeCompare(b.name, 'zh-CN');
                    });

                    return entries;
                };

                const nodes = buildNodes(treeDictionary);

                const expanded = { ...this.expandedFolders };
                const validFolderPaths = new Set();

                const ensureExpansion = (list, depth = 0) => {
                    list.forEach((item) => {
                        if (item.type === 'folder') {
                            validFolderPaths.add(item.path);
                            if (expanded[item.path] === undefined) {
                                expanded[item.path] = false;
                            }
                            ensureExpansion(item.children || [], depth + 1);
                        }
                    });
                };

                ensureExpansion(nodes);

                Object.keys(expanded).forEach((path) => {
                    if (!validFolderPaths.has(path)) {
                        delete expanded[path];
                    }
                });

                this.expandedFolders = expanded;
                this.fileTree = nodes;
            },

            toggleFolder(path) {
                this.hideContextMenu();
                if (!path) {
                    return;
                }
                const current = !!this.expandedFolders[path];
                this.expandedFolders = {
                    ...this.expandedFolders,
                    [path]: !current
                };
            },

            cycleSidebarPanel() {
                if (this.isSubAgentView) {
                    this.panelMode = this.panelMode === 'files' ? 'todo' : 'files';
                    if (this.panelMode === 'files') {
                        this.fetchSubAgentFileTree();
                    } else {
                        this.fetchTodoList();
                    }
                    return;
                }
                const order = ['files', 'todo', 'subAgents'];
                const nextIndex = (order.indexOf(this.panelMode) + 1) % order.length;
                this.panelMode = order[nextIndex];
                if (this.panelMode === 'subAgents') {
                    this.fetchSubAgents();
                }
            },

            formatTaskStatus(task) {
                if (!task) {
                    return '';
                }
                return task.status === 'done'
                    ? `${this.todoDoneEmoji} 完成`
                    : `${this.todoPendingEmoji} 未完成`;
            },

            toolCategoryEmoji(categoryId) {
                return this.toolCategoryEmojis[categoryId] || '⚙️';
            },

            async fetchSubAgents() {
                if (this.isSubAgentView) {
                    return;
                }
                try {
                    const resp = await fetch('/api/sub_agents');
                    if (!resp.ok) {
                        throw new Error(await resp.text());
                    }
                    const data = await resp.json();
                    if (data.success) {
                        this.subAgents = Array.isArray(data.data) ? data.data : [];
                    }
                } catch (error) {
                    console.error('获取子智能体列表失败:', error);
                }
            },

            getSubAgentBaseUrl() {
                const override = window.SUB_AGENT_BASE_URL || window.__SUB_AGENT_BASE_URL__;
                if (override && typeof override === 'string') {
                    return override.replace(/\/$/, '');
                }
                const { protocol, hostname } = window.location;
                if (hostname && hostname.includes('agent.')) {
                    const mappedHost = hostname.replace('agent.', 'subagent.');
                    return `${protocol}//${mappedHost}`;
                }
                return `${protocol}//${hostname}:8092`;
            },

            openSubAgent(agent) {
                if (this.isSubAgentView || !agent || !agent.task_id) {
                    return;
                }
                const parentConv = agent.conversation_id || this.currentConversationId || '';
                const convSegment = this.stripConversationPrefix(parentConv);
                const agentLabel = agent.agent_id ? `sub_agent${agent.agent_id}` : agent.task_id;
                const base = this.getSubAgentBaseUrl();
                const pathSuffix = convSegment
                    ? `/${convSegment}+${agentLabel}`
                    : `/sub_agent/${agent.task_id}`;
                const params = new URLSearchParams();
                params.set('task_id', agent.task_id);
                if (agent.conversation_id) {
                    params.set('conversation_id', agent.conversation_id);
                }
                const url = `${base}${pathSuffix}?${params.toString()}`;
                window.open(url, '_blank');
            },

            async fetchTodoList() {
                if (this.isSubAgentView) {
                    return;
                }
                try {
                    const response = await fetch('/api/todo-list');
                    const data = await response.json();
                    if (data.success) {
                        this.todoList = data.data || null;
                    }
                } catch (error) {
                    console.error('获取待办列表失败:', error);
                }
            },

            triggerFileUpload() {
                if (this.uploading) {
                    return;
                }
                const input = this.$refs.fileUploadInput;
                if (input) {
                    input.click();
                }
            },

            handleFileSelected(event) {
                const fileInput = event?.target;
                if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
                    return;
                }
                const [file] = fileInput.files;
                this.uploadSelectedFile(file);
            },

            resetFileInput() {
                const input = this.$refs.fileUploadInput;
                if (input) {
                    input.value = '';
                }
            },

            async uploadSelectedFile(file) {
                if (!file || this.uploading) {
                    this.resetFileInput();
                    return;
                }

                this.uploading = true;

                try {
                    const formData = new FormData();
                    formData.append('file', file);
                    formData.append('filename', file.name || '');

                    const response = await fetch('/api/upload', {
                        method: 'POST',
                        body: formData
                    });

                    let result = {};
                    try {
                        result = await response.json();
                    } catch (parseError) {
                        throw new Error('服务器响应无法解析');
                    }

                    if (!response.ok || !result.success) {
                        const message = result.error || result.message || '上传失败';
                        throw new Error(message);
                    }

                    await this.refreshFileTree();
                    alert(`上传成功：${result.path || file.name}`);
                } catch (error) {
                    console.error('文件上传失败:', error);
                    alert(`文件上传失败：${error.message}`);
                } finally {
                    this.uploading = false;
                    this.resetFileInput();
                }
            },
            
            handleSendOrStop() {
                if (this.streamingMessage) {
                    this.stopTask();
                } else {
                    this.sendMessage();
                }
            },

            async sendMessage() {
                if (this.isSubAgentView) {
                    await this.sendSubAgentMessage();
                    return;
                }
                if (this.streamingMessage || !this.isConnected) {
                    return;
                }

                if (!this.inputMessage.trim()) {
                    return;
                }
                
                const message = this.inputMessage;
                
                if (message.startsWith('/')) {
                    this.socket.emit('send_command', { command: message });
                    this.inputMessage = '';
                    this.settingsOpen = false;
                    return;
                }
                
                this.messages.push({
                    role: 'user',
                    content: message
                });
                
                this.currentMessageIndex = -1;
                this.socket.emit('send_message', { message: message, conversation_id: this.currentConversationId });
                this.inputMessage = '';
                this.autoScrollEnabled = true;
                this.scrollToBottom();
                this.settingsOpen = false;
                
                // 发送消息后延迟更新当前上下文Token（关键修复：恢复原逻辑）
                setTimeout(() => {
                    if (this.currentConversationId) {
                    }
                }, 1000);
            },
            
            // 新增：停止任务方法
            stopTask() {
                if (this.isSubAgentView) {
                    this.stopSubAgentTask();
                    return;
                }
                if (this.streamingMessage && !this.stopRequested) {
                    this.socket.emit('stop_task');
                    this.stopRequested = true;
                    console.log('发送停止请求');
                }
                this.settingsOpen = false;
            },
            
            clearChat() {
                if (confirm('确定要清除所有对话记录吗？')) {
                    this.socket.emit('send_command', { command: '/clear' });
                }
                this.settingsOpen = false;
            },

            async compressConversation() {
                if (!this.currentConversationId) {
                    alert('当前没有可压缩的对话。');
                    return;
                }

                if (this.compressing) {
                    return;
                }

                const confirmed = confirm('确定要压缩当前对话记录吗？压缩后会生成新的对话副本。');
                if (!confirmed) {
                    return;
                }

                this.settingsOpen = false;
                this.compressing = true;

                try {
                    const response = await fetch(`/api/conversations/${this.currentConversationId}/compress`, {
                        method: 'POST'
                    });

                    const result = await response.json();

                    if (response.ok && result.success) {
                        const newId = result.compressed_conversation_id;
                        if (newId) {
                            this.currentConversationId = newId;
                        }
                        console.log('对话压缩完成:', result);
                    } else {
                        const message = result.message || result.error || '压缩失败';
                        alert(`压缩失败: ${message}`);
                    }
                } catch (error) {
                    console.error('压缩对话异常:', error);
                    alert(`压缩对话异常: ${error.message}`);
                } finally {
                    this.compressing = false;
                }
            },

            toggleToolMenu() {
                if (!this.isConnected) {
                    return;
                }
                const nextState = !this.toolMenuOpen;
                this.toolMenuOpen = nextState;
                if (nextState) {
                    this.settingsOpen = false;
                    this.loadToolSettings();
                }
            },

            handleClickOutsideToolMenu(event) {
                if (!this.toolMenuOpen) {
                    return;
                }
                const dropdown = this.$refs.toolDropdown;
                if (dropdown && !dropdown.contains(event.target)) {
                    this.toolMenuOpen = false;
                }
            },

            applyToolSettingsSnapshot(categories) {
                if (!Array.isArray(categories)) {
                    return;
                }
                this.toolSettings = categories.map((item) => ({
                    id: item.id,
                    label: item.label || item.id,
                    enabled: !!item.enabled,
                    tools: Array.isArray(item.tools) ? item.tools : []
                }));
                this.toolSettingsLoading = false;
            },

            async loadToolSettings(force = false) {
                if (!this.isConnected) {
                    return;
                }
                if (this.toolSettingsLoading) {
                    return;
                }
                if (!force && this.toolSettings.length > 0) {
                    return;
                }
                this.toolSettingsLoading = true;
                try {
                    const response = await fetch('/api/tool-settings');
                    const data = await response.json();
                    if (response.ok && data.success && Array.isArray(data.categories)) {
                        this.applyToolSettingsSnapshot(data.categories);
                    } else {
                        console.warn('获取工具设置失败:', data);
                        this.toolSettingsLoading = false;
                    }
                } catch (error) {
                    console.error('获取工具设置异常:', error);
                    this.toolSettingsLoading = false;
                }
            },

            async updateToolCategory(categoryId, enabled) {
                if (!this.isConnected) {
                    return;
                }
                if (this.toolSettingsLoading) {
                    return;
                }
                const previousSnapshot = this.toolSettings.map((item) => ({ ...item }));
                this.toolSettings = this.toolSettings.map((item) => {
                    if (item.id === categoryId) {
                        return { ...item, enabled };
                    }
                    return item;
                });
                try {
                    const response = await fetch('/api/tool-settings', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({
                            category: categoryId,
                            enabled
                        })
                    });
                    const data = await response.json();
                    if (response.ok && data.success && Array.isArray(data.categories)) {
                        this.applyToolSettingsSnapshot(data.categories);
                    } else {
                        console.warn('更新工具设置失败:', data);
                        this.toolSettings = previousSnapshot;
                    }
                } catch (error) {
                    console.error('更新工具设置异常:', error);
                    this.toolSettings = previousSnapshot;
                }
                this.toolSettingsLoading = false;
            },

            toggleSettings() {
                if (!this.isConnected) {
                    return;
                }
                this.settingsOpen = !this.settingsOpen;
                if (this.settingsOpen) {
                    this.toolMenuOpen = false;
                }
            },

            toggleFocusPanel() {
                this.rightCollapsed = !this.rightCollapsed;
                if (!this.rightCollapsed && this.rightWidth < this.minPanelWidth) {
                    this.rightWidth = this.minPanelWidth;
                }
                this.settingsOpen = false;
            },

            handleClickOutsideSettings(event) {
                if (!this.settingsOpen) {
                    return;
                }
                const dropdown = this.$refs.settingsDropdown;
                if (dropdown && !dropdown.contains(event.target)) {
                    this.settingsOpen = false;
                }
            },
            
            addSystemMessage(content) {
                this.appendSystemAction(content);
            },

            appendSystemAction(content) {
                const msg = this.ensureAssistantMessage();
                msg.actions.push({
                    id: `system-${Date.now()}-${Math.random()}`,
                    type: 'system',
                    content: content,
                    timestamp: Date.now()
                });
                this.$forceUpdate();
                this.conditionalScrollToBottom();
            },
            
            toggleBlock(id) {
                if (this.expandedBlocks.has(id)) {
                    this.expandedBlocks.delete(id);
                } else {
                    this.expandedBlocks.add(id);
                }
                this.$forceUpdate();
            },
            
            // 修复：工具相关方法 - 接收tool对象而不是name
            getToolIcon(tool) {
                const toolName = typeof tool === 'string' ? tool : tool.name;
                const icons = {
                    'create_file': '📄',
                    'sleep': '⏱️',
                    'read_file': '📖',
                    'ocr_image': '📸',
                    'delete_file': '🗑️',
                    'rename_file': '✏️',
                    'modify_file': '✏️',
                    'append_to_file': '✏️',
                    'create_folder': '📁',
                    'focus_file': '👁️',
                    'unfocus_file': '👁️',
                    'web_search': '🔍',
                    'extract_webpage': '🌐',
                    'save_webpage': '💾',
                    'run_python': '🐍',
                    'run_command': '$',
                    'update_memory': '🧠',
                    'terminal_session': '💻',
                    'terminal_input': '⌨️',
                    'terminal_snapshot': '📋',
                    'terminal_reset': '♻️',
                    'todo_create': '🗒️',
                    'todo_update_task': '☑️',
                    'todo_finish': '🏁',
                    'todo_finish_confirm': '❗',
                    'create_sub_agent': '🤖',
                    'wait_sub_agent': '⏳'
                };
                return icons[toolName] || '⚙️';
            },
            
            getToolAnimationClass(tool) {
                // 根据工具状态返回不同的动画类
                if (tool.status === 'hinted') {
                    return 'hint-animation pulse-slow';
                } else if (tool.status === 'preparing') {
                    return 'preparing-animation';
                } else if (tool.status === 'running') {
                    const animations = {
                        'create_file': 'file-animation',
                        'read_file': 'read-animation',
                        'delete_file': 'file-animation',
                        'rename_file': 'file-animation',
                        'modify_file': 'file-animation',
                        'append_to_file': 'file-animation',
                        'create_folder': 'file-animation',
                        'focus_file': 'focus-animation',
                        'unfocus_file': 'focus-animation',
                        'web_search': 'search-animation',
                        'extract_webpage': 'search-animation',
                        'save_webpage': 'file-animation',
                        'run_python': 'code-animation',
                        'run_command': 'terminal-animation',
                        'update_memory': 'memory-animation',
                        'sleep': 'wait-animation',
                        'terminal_session': 'terminal-animation',
                        'terminal_input': 'terminal-animation',
                        'terminal_snapshot': 'terminal-animation',
                        'terminal_reset': 'terminal-animation',
                        'todo_create': 'file-animation',
                        'todo_update_task': 'file-animation',
                        'todo_finish': 'file-animation',
                        'todo_finish_confirm': 'file-animation',
                        'create_sub_agent': 'terminal-animation',
                        'wait_sub_agent': 'wait-animation'
                    };
                    return animations[tool.name] || 'default-animation';
                }
                return '';
            },
            
            // 修复：获取工具状态文本
            getToolStatusText(tool) {
                // 优先使用自定义消息
                if (tool.message) {
                    return tool.message;
                }
                
                if (tool.status === 'hinted') {
                    return `可能需要 ${tool.name}...`;
                } else if (tool.status === 'preparing') {
                    return `准备调用 ${tool.name}...`;
                } else if (tool.status === 'running') {
                    const texts = {
                        'create_file': '正在创建文件...',
                        'sleep': '正在等待...',
                        'delete_file': '正在删除文件...',
                        'rename_file': '正在重命名文件...',
                        'modify_file': '正在修改文件...',
                        'append_to_file': '正在追加文件...',
                        'create_folder': '正在创建文件夹...',
                        'focus_file': '正在聚焦文件...',
                        'unfocus_file': '正在取消聚焦...',
                        'web_search': '正在搜索网络...',
                        'extract_webpage': '正在提取网页...',
                        'save_webpage': '正在保存网页...',
                        'run_python': '正在执行Python代码...',
                        'run_command': '正在执行命令...',
                        'update_memory': '正在更新记忆...',
                        'terminal_session': '正在管理终端会话...',
                        'terminal_input': '正在发送终端输入...',
                        'terminal_snapshot': '正在获取终端快照...',
                        'terminal_reset': '正在重置终端...'
                    };
                    if (tool.name === 'read_file') {
                        const readType = ((tool.argumentSnapshot && tool.argumentSnapshot.type) ||
                            (tool.arguments && tool.arguments.type) || 'read').toLowerCase();
                        const runningMap = {
                            'read': '正在读取文件...',
                            'search': '正在执行搜索...',
                            'extract': '正在提取内容...'
                        };
                        return runningMap[readType] || '正在读取文件...';
                    }
                    return texts[tool.name] || '正在执行...';
                } else if (tool.status === 'completed') {
                    // 修复：完成状态的文本
                    const texts = {
                        'create_file': '文件创建成功',
                        'delete_file': '文件删除成功',
                        'sleep': '等待完成',
                        'rename_file': '文件重命名成功',
                        'modify_file': '文件修改成功',
                        'append_to_file': '文件追加完成',
                        'create_folder': '文件夹创建成功',
                        'focus_file': '文件聚焦成功',
                        'unfocus_file': '取消聚焦成功',
                        'web_search': '搜索完成',
                        'extract_webpage': '网页提取完成',
                        'save_webpage': '网页保存完成（纯文本）',
                        'run_python': '代码执行完成',
                        'run_command': '命令执行完成',
                        'update_memory': '记忆更新成功',
                        'terminal_session': '终端操作完成',
                        'terminal_input': '终端输入完成',
                        'terminal_snapshot': '终端快照已返回',
                        'terminal_reset': '终端已重置'
                    };
                    if (tool.name === 'read_file' && tool.result && typeof tool.result === 'object') {
                        const readType = (tool.result.type || 'read').toLowerCase();
                        if (readType === 'search') {
                            const query = tool.result.query ? `「${tool.result.query}」` : '';
                            const count = typeof tool.result.returned_matches === 'number'
                                ? tool.result.returned_matches
                                : (tool.result.actual_matches || 0);
                            return `搜索${query}，得到${count}个结果`;
                        } else if (readType === 'extract') {
                            const segments = Array.isArray(tool.result.segments) ? tool.result.segments : [];
                            const totalLines = segments.reduce((sum, seg) => {
                                const start = Number(seg.line_start) || 0;
                                const end = Number(seg.line_end) || 0;
                                if (!start || !end || end < start) return sum;
                                return sum + (end - start + 1);
                            }, 0);
                            const displayLines = totalLines || tool.result.char_count || 0;
                            return `提取了${displayLines}行`;
                        }
                        return '文件读取完成';
                    }
                    return texts[tool.name] || '执行完成';
                } else {
                    // 其他状态
                    return `${tool.name} - ${tool.status}`;
                }
            },
            
            getToolDescription(tool) {
                const args = tool.argumentSnapshot || tool.arguments;
                const argumentLabel = tool.argumentLabel || this.buildToolLabel(args);
                if (argumentLabel) {
                    return argumentLabel;
                }
                if (tool.statusDetail) {
                    return tool.statusDetail;
                }
                if (tool.result && typeof tool.result === 'object') {
                    if (tool.result.path) {
                        return tool.result.path.split('/').pop();
                    }
                }
                return '';
            },

            cloneToolArguments(args) {
                if (!args || typeof args !== 'object') {
                    return null;
                }
                try {
                    return JSON.parse(JSON.stringify(args));
                } catch (error) {
                    console.warn('无法克隆工具参数:', error);
                    return { ...args };
                }
            },

            buildToolLabel(args) {
                if (!args || typeof args !== 'object') {
                    return '';
                }
                if (args.command) {
                    return args.command;
                }
                if (args.path) {
                    return args.path.split('/').pop();
                }
                if (args.target_path) {
                    return args.target_path.split('/').pop();
                }
                if (args.query) {
                    return `"${args.query}"`;
                }
                if (args.seconds !== undefined) {
                    return `${args.seconds} 秒`;
                }
                if (args.name) {
                    return args.name;
                }
                return '';
            },

            formatSearchTopic(filters) {
                const mapping = {
                    'general': '通用',
                    'news': '新闻',
                    'finance': '金融'
                };
                const topic = (filters && filters.topic) ? String(filters.topic).toLowerCase() : 'general';
                return mapping[topic] || '通用';
            },

            formatSearchTime(filters) {
                if (!filters) {
                    return '未限定时间';
                }
                if (filters.time_range) {
                    const mapping = {
                        'day': '过去24小时',
                        'week': '过去7天',
                        'month': '过去30天',
                        'year': '过去365天'
                    };
                    return mapping[filters.time_range] || `相对范围：${filters.time_range}`;
                }
                if (typeof filters.days === 'number') {
                    return `过去${filters.days}天`;
                }
                if (filters.start_date && filters.end_date) {
                    return `${filters.start_date} 至 ${filters.end_date}`;
                }
                return '未限定时间';
            },
            
            renderMarkdown(text, isStreaming = false) {
                if (!text) return '';
                
                if (typeof marked === 'undefined') {
                    return text;
                }
                
                marked.setOptions({
                    breaks: true,
                    gfm: true,
                    sanitize: false
                });
                
                if (!isStreaming) {
                    if (!this.markdownCache) {
                        this.markdownCache = new Map();
                    }
                    
                    const cacheKey = `${text.length}_${text.substring(0, 100)}`;
                    
                    if (this.markdownCache.has(cacheKey)) {
                        return this.markdownCache.get(cacheKey);
                    }
                }
                
                let html = marked.parse(text);
                html = this.wrapCodeBlocks(html, isStreaming);
                
                if (!isStreaming && text.length < 10000) {
                    if (!this.markdownCache) {
                        this.markdownCache = new Map();
                    }
                    this.markdownCache.set(`${text.length}_${text.substring(0, 100)}`, html);
                    if (this.markdownCache.size > 20) {
                        const firstKey = this.markdownCache.keys().next().value;
                        this.markdownCache.delete(firstKey);
                    }
                }
                
                // 只在非流式状态处理（流式状态由renderLatexInRealtime处理）
                if (!isStreaming) {
                    setTimeout(() => {
                        // 代码高亮
                        if (typeof Prism !== 'undefined') {
                            const codeBlocks = document.querySelectorAll('.code-block-wrapper pre code:not([data-highlighted])');
                            codeBlocks.forEach(block => {
                                try {
                                    Prism.highlightElement(block);
                                    block.setAttribute('data-highlighted', 'true');
                                } catch (e) {
                                    console.warn('代码高亮失败:', e);
                                }
                            });
                        }
                        
                        // LaTeX最终渲染
                        if (typeof renderMathInElement !== 'undefined') {
                            const elements = document.querySelectorAll('.text-output .text-content:not(.streaming-text)');
                            elements.forEach(element => {
                                if (element.hasAttribute('data-math-rendered')) return;
                                
                                try {
                                    renderMathInElement(element, {
                                        delimiters: [
                                            {left: '$$', right: '$$', display: true},
                                            {left: '$', right: '$', display: false},
                                            {left: '\\[', right: '\\]', display: true},
                                            {left: '\\(', right: '\\)', display: false}
                                        ],
                                        throwOnError: false,
                                        trust: true
                                    });
                                    element.setAttribute('data-math-rendered', 'true');
                                } catch (e) {
                                    console.warn('LaTeX渲染失败:', e);
                                }
                            });
                        }
                    }, 100);
                }
                
                return html;
            },
            // 实时LaTeX渲染（用于流式输出）
            renderLatexInRealtime() {
                if (typeof renderMathInElement === 'undefined') {
                    return;
                }
                
                // 使用requestAnimationFrame优化性能
                if (this._latexRenderTimer) {
                    cancelAnimationFrame(this._latexRenderTimer);
                }
                
                this._latexRenderTimer = requestAnimationFrame(() => {
                    const elements = document.querySelectorAll('.text-output .streaming-text');
                    elements.forEach(element => {
                        try {
                            renderMathInElement(element, {
                                delimiters: [
                                    {left: '$$', right: '$$', display: true},
                                    {left: '$', right: '$', display: false},
                                    {left: '\\[', right: '\\]', display: true},
                                    {left: '\\(', right: '\\)', display: false}
                                ],
                                throwOnError: false,
                                trust: true
                            });
                        } catch (e) {
                            // 忽略错误，继续渲染
                        }
                    });
                });
            },
            // 用字符串替换包装代码块
            // 用字符串替换包装代码块 - 添加streaming参数
            wrapCodeBlocks(html, isStreaming = false) {
                // 如果是流式输出，不包装代码块，保持原样
                if (isStreaming) {
                    return html;
                }
                
                let counter = 0;
                
                // 匹配 <pre><code ...>...</code></pre>
                return html.replace(/<pre><code([^>]*)>([\s\S]*?)<\/code><\/pre>/g, (match, attributes, content) => {
                    // 提取语言
                    const langMatch = attributes.match(/class="[^"]*language-(\w+)/);
                    const language = langMatch ? langMatch[1] : 'text';
                    
                    // 生成唯一ID
                    const blockId = `code-${Date.now()}-${counter++}`;
                    
                    // 转义引号用于data属性
                    const escapedContent = content
                        .replace(/&/g, '&amp;')
                        .replace(/</g, '&lt;')
                        .replace(/>/g, '&gt;')
                        .replace(/"/g, '&quot;');
                    
                    // 构建新的HTML，保持code元素原样
                    return `
            <div class="code-block-wrapper">
                <div class="code-block-header">
                    <span class="code-language">${language}</span>
                    <button class="copy-code-btn" data-code="${blockId}" title="复制代码">📋</button>
                </div>
                <pre><code${attributes} data-code-id="${blockId}" data-original-code="${escapedContent}">${content}</code></pre>
            </div>`;
                });
            },
            
            getLanguageClass(path) {
                const ext = path.split('.').pop().toLowerCase();
                const langMap = {
                    'py': 'language-python',
                    'js': 'language-javascript',
                    'html': 'language-html',
                    'css': 'language-css',
                    'json': 'language-json',
                    'md': 'language-markdown',
                    'txt': 'language-plain'
                };
                return langMap[ext] || 'language-plain';
            },
            
            scrollToBottom() {
                setTimeout(() => {
                    const messagesArea = this.$refs.messagesArea;
                    if (messagesArea) {
                        // 标记为程序触发的滚动
                        if (this._setScrollingFlag) {
                            this._setScrollingFlag(true);
                        }
                        
                        messagesArea.scrollTop = messagesArea.scrollHeight;
                        
                        // 滚动完成后重置标记
                        setTimeout(() => {
                            if (this._setScrollingFlag) {
                                this._setScrollingFlag(false);
                            }
                        }, 100);
                    }
                }, 50);
            },
            
            conditionalScrollToBottom() {
                // 严格检查：只在明确允许时才滚动
                if (this.autoScrollEnabled === true && this.userScrolling === false) {
                    this.scrollToBottom();
                }
            },
            
            toggleScrollLock() {
                const currentlyLocked = this.autoScrollEnabled && !this.userScrolling;
                if (currentlyLocked) {
                    this.autoScrollEnabled = false;
                    this.userScrolling = true;
                } else {
                    this.autoScrollEnabled = true;
                    this.userScrolling = false;
                    this.scrollToBottom();
                }
            },

            scrollThinkingToBottom(blockId) {
                if (!this.thinkingScrollLocks.get(blockId)) return;
                const refName = `thinkingContent-${blockId}`;
                const elRef = this.$refs[refName];
                const el = Array.isArray(elRef) ? elRef[0] : elRef;
                if (el) {
                    el.scrollTop = el.scrollHeight;
                }
            },

            handleThinkingScroll(blockId, event) {
                const el = event.target;
                const threshold = 12;
                const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < threshold;
                this.thinkingScrollLocks.set(blockId, atBottom);
            },
            
            // 面板调整方法
            startResize(panel, event) {
                this.isResizing = true;
                this.resizingPanel = panel;
                if (panel === 'right' && this.rightCollapsed) {
                    this.rightCollapsed = false;
                    if (this.rightWidth < this.minPanelWidth) {
                        this.rightWidth = this.minPanelWidth;
                    }
                }
                document.addEventListener('mousemove', this.handleResize);
                document.addEventListener('mouseup', this.stopResize);
                document.body.style.userSelect = 'none';
                document.body.style.cursor = 'col-resize';
                event.preventDefault();
            },
            
            handleResize(event) {
                if (!this.isResizing) return;
                
                const containerWidth = document.querySelector('.main-container').offsetWidth;
                
                if (this.resizingPanel === 'left') {
                    let newWidth = event.clientX - (this.sidebarCollapsed ? 60 : 300);
                    newWidth = Math.max(this.minPanelWidth, Math.min(newWidth, this.maxPanelWidth));
                    this.leftWidth = newWidth;
                } else if (this.resizingPanel === 'right') {
                    let newWidth = containerWidth - event.clientX;
                    newWidth = Math.max(this.minPanelWidth, Math.min(newWidth, this.maxPanelWidth));
                    this.rightWidth = newWidth;
                } else if (this.resizingPanel === 'conversation') {
                    // 对话侧边栏宽度调整
                    let newWidth = event.clientX;
                    newWidth = Math.max(200, Math.min(newWidth, 400));
                    // 这里可以动态调整对话侧边栏宽度，暂时不实现
                }
            },
            
            stopResize() {
                this.isResizing = false;
                this.resizingPanel = null;
                document.removeEventListener('mousemove', this.handleResize);
                document.removeEventListener('mouseup', this.stopResize);
                document.body.style.userSelect = '';
                document.body.style.cursor = '';
            }
        }
    });
    
    app.component('file-node', {
        name: 'FileNode',
        props: {
            node: {
                type: Object,
                required: true
            },
            level: {
                type: Number,
                default: 0
            },
            expandedFolders: {
                type: Object,
                required: true
            }
        },
        emits: ['toggle-folder', 'context-menu'],
        computed: {
            isExpanded() {
                if (this.node.type !== 'folder') {
                    return false;
                }
                const value = this.expandedFolders[this.node.path];
                return value === undefined ? true : value;
            },
            folderPadding() {
                return {
                    paddingLeft: `${12 + this.level * 16}px`
                };
            },
            filePadding() {
                return {
                    paddingLeft: `${40 + this.level * 16}px`
                };
            }
        },
        methods: {
            toggle() {
                if (this.node.type === 'folder') {
                    this.$emit('toggle-folder', this.node.path);
                }
            }
        },
        template: `
            <div class="file-node-wrapper" @contextmenu.stop.prevent="$emit('context-menu', { node, event: $event })">
                <div v-if="node.type === 'folder'" class="file-node folder-node">
                    <button class="folder-header" type="button" :style="folderPadding" @click="toggle">
                        <span class="folder-arrow">{{ isExpanded ? '▾' : '▸' }}</span>
                        <span class="folder-icon">{{ isExpanded ? '📂' : '📁' }}</span>
                        <span class="folder-name">{{ node.name }}</span>
                    </button>
                    <div v-show="isExpanded" class="folder-children">
                        <file-node
                            v-for="child in node.children"
                            :key="child.path"
                            :node="child"
                            :level="level + 1"
                            :expanded-folders="expandedFolders"
                            @toggle-folder="$emit('toggle-folder', $event)"
                            @context-menu="$emit('context-menu', $event)"
                        ></file-node>
                    </div>
                </div>
                <div v-else class="file-node file-leaf" :style="filePadding">
                    <span class="file-icon">📄</span>
                    <span class="file-name">{{ node.name }}</span>
                    <span v-if="node.annotation" class="annotation">{{ node.annotation }}</span>
                </div>
            </div>
        `
    });

    app.mount('#app');
    console.log('Vue应用初始化完成');
}

window.addEventListener('load', () => {
    bootstrapApp();
});
