Task configuration:
{"task_id": "12", "task_name": "check_zoom_level", "description": "\u68c0\u67e5Joplin\u7684\u89c6\u56fe\u7f29\u653e\u72b6\u6001", "application_info": {"name": "joplin", "executable_path": "/workspace/PC-Canary/apps/joplin/Joplin-3.3.12.AppImage", "args": ["--env", "dev", "--profile", "/workspace/PC-Canary/apps/joplin/joplindev-desktop"]}, "task_parameters": {"zoom_level": 110}, "instruction_template": "\u5728Joplin\u4e2d\u5c06\u89c6\u56fe\u7f29\u653e\u6bd4\u4f8b\u8bbe\u7f6e\u4e3a ${zoom_level} %", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js"}, {"role": "handler", "path": "handler.py"}], "timeout": 10, "evaluator_type": "IpcInjector", "evaluate_on_completion": true}, "total_key_steps": 1, "preconditions": {"joplin_running": true}, "events": {"evaluate_on_completion": {"description": "\u5728\u4efb\u52a1\u7ed3\u675f\u65f6\u5224\u65ad\u89c6\u56fe\u7f29\u653e\u6bd4\u4f8b\u662f\u5426\u7b26\u5408\u9884\u671f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u89c6\u56fe\u7f29\u653e\u6bd4\u4f8b\u8bbe\u7f6e\u5b8c\u6210"}}, "mcp_servers": [{"command": "/home/user/.local/bin/uv", "args": ["--directory", "/home/user/Desktop/joplin-mcp-server", "run", "src/mcp/joplin_mcp.py"]}]}

Hook script:
joplin.plugins.register({
    onStart: async function() {
        console.log('Joplin plugin started');

        // 监听 evaluate 事件
        socket.on("evaluate", async () => {
            console.log('Task12_checkZoomLevel---------------------------');
            try {
                // 获取当前缩放比例
                const zoomLevel = await joplin.settings.globalValue('windowContentZoomFactor');
                // 确保转换为数值类型
                const zoomValue = parseFloat(zoomLevel) || 1.0;
                console.log('Current zoom level:', zoomValue);
                
                // 使用 postMessage 发送评估消息
                window.postMessage({
                    "event_type": "evaluate_on_completion",
                    "message": "任务结束时Joplin的缩放比例是" + zoomValue,
                    "data": zoomValue
                }, '*');
                console.log('Evaluation result sent via postMessage');
            } catch (error) {
                console.error('Error in evaluate handler:', error);
            }
        });
    }
});

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

"""
joplin检查视图缩放比例的事件处理器
负责处理钩子脚本产生的事件并更新评估指标
"""

from typing import Dict, Any, Optional, 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.get('message'))
    
    # 打印完整的参数信息
    logger.info("="*50)
    logger.info("参数调试信息:")
    logger.info(f"message 类型: {type(message)}")
    logger.info(f"message 内容: {message}")
    logger.info(f"message.get('data') 类型: {type(message.get('data'))}")
    logger.info(f"message.get('data') 内容: {message.get('data')}")
    logger.info(f"task_parameter 类型: {type(task_parameter)}")
    logger.info(f"task_parameter 内容: {task_parameter}")
    logger.info("="*50)
    
    if event_type == "evaluate_on_completion":
        try:
            # 获取当前缩放比例
            data = message.get("data")
            logger.info(f"data 类型: {type(data)}")
            logger.info(f"data 内容: {data}")
            
            current_zoom = float(data) if data is not None else 1.0
            expected_zoom = float(task_parameter.get('zoom_level', 1.0))
            
            logger.info(f"正在检测缩放比例是否为: {expected_zoom}")
            logger.info(f"当前Joplin缩放比例为: {current_zoom}")
            
            # 允许0.01的误差范围
            if abs(current_zoom - expected_zoom) < 0.01:
                return [
                    {"status": "key_step", "index": 1},
                    {"status": "success", "reason": f"视图缩放比例已经成功设置为{expected_zoom}"}
                ]
            else:
                return [{"status": "error", "type": "evaluate_on_completion", "message": f"缩放比例不匹配，期望：{expected_zoom}，实际：{current_zoom}"}]
        except (TypeError, ValueError) as e:
            logger.error(f"数据类型转换错误: {str(e)}")
            logger.error(f"错误详情 - data类型: {type(data)}, data值: {data}")
            return [{"status": "error", "type": "evaluate_on_completion", "message": f"数据类型错误: {str(e)}"}]
    return None