Task configuration:
{"task_id": "07", "task_name": "open_new_window", "description": "\u5c06\u6307\u5b9a\u76ee\u5f55\u5728\u4e00\u4e2a\u65b0\u7684vscode\u5e94\u7528\u7a97\u53e3\u4e2d\u6253\u5f00", "application_info": {"name": "vscode", "executable_path": "/usr/share/code/code", "args": ["--no-sandbox", "--user-data-dir=/root/vscode_user_data_dir/"]}, "task_parameters": {"work_space_dir": "/root/C-Plus-Plus/data_structures"}, "instruction_template": "\u5728\u5f53\u524dvscode\u7a97\u53e3\u4e0a\u9644\u52a0\u65b0\u7684\u7a97\u53e3, \u5e76\u4e14\u5728\u65b0\u7a97\u53e3\u6253\u5f00\u76ee\u5f55 ${work_space_dir}", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js"}, {"role": "handler", "path": "handler.py"}], "timeout": 120, "evaluator_type": "IpcInjector", "evaluate_on_completion": false}, "total_key_steps": 1, "preconditions": {"vscode_running": true}, "events": {"get_work_spaces": {"description": "\u83b7\u53d6\u5df2\u7ecf\u6253\u5f00\u7684\u5de5\u4f5c\u533a\u7684\u76ee\u5f55", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u6210\u529f\u6253\u5f00\u5de5\u4f5c\u533a"}}, "mcp_servers": [{"command": "mcp-proxy", "args": ["http://127.0.0.1:6010/sse"]}], "context_data": [{"from": "tests/context_data/vscode/user_data", "to": "/root/vscode_user_data_dir"}, {"from": "tests/context_data/vscode/extensions", "to": "/root/.vscode/"}, {"from": "tests/context_data/vscode/C-Plus-Plus", "to": "/root/C-Plus-Plus"}]}

Hook script:
/**
 * 获取当前 VS Code 实例中所有工作区的路径
 * @returns {Promise<string[]>} 工作区路径数组
 */
async function getWorkspacePaths() {
    try {
        // 获取当前 VS Code 实例的所有工作区文件夹
        const workspaceFolders = vscode.workspace.workspaceFolders || [];

        // 提取工作区路径并去重
        const uniqueWorkspacePaths = [...new Set(
            workspaceFolders.map(folder => folder.uri.fsPath)
        )];

        return uniqueWorkspacePaths;
    } catch (error) {
        throw new Error(`获取工作区路径失败: ${error.message}`);
    }
}

getWorkspacePaths().then(work_spaces => {
    socket.emit("send", {
        'event_type': "get_work_spaces",
        'message': "任务开始时获取所有打开的工作区路径",
        'work_spaces': work_spaces
    });
});

// Listen for 'evaluate' event
socket.on('evaluate', async () => {
    socket.emit("send", {
        'event_type': "evaluate_on_completion",
        'message': "任务失败"
    });
});

Evaluation handler:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from typing import Dict, Any, Optional, Callable, List

def message_handler(message: Dict[str, Any], logger, task_parameter: Dict[str, Any]) -> Optional[List[Dict[str, Any]]]:    
    event_type = message.get('event_type')
    logger.info(message)
    if event_type == "get_work_spaces":
        work_spaces = message.get('work_spaces')
        expected_work_space = task_parameter.get("work_space_dir", "/root/C-Plus-Plus/data_structures")
        if len(work_spaces) == 1 and expected_work_space == work_spaces[0]:
            return [
                {"status": "key_step", "index": 1},
                {"status": "success", "reason": f"任务成功完成"}
            ]
    elif event_type == "evaluate_on_completion":
        return [{"status": "error", "type": "evaluate_on_completion", "message": "任务没有完成"}]
    return None