Task configuration:
{"task_id": "19", "task_name": "sort_notes_by_title_desc", "description": "\u5728Joplin\u4e2d\u5c06\u5f53\u524d\u7b14\u8bb0\u9875\u9762\u7684\u6392\u5e8f\u65b9\u5f0f\u4fee\u6539\u4e3a\u6807\u9898\u5012\u5e8f\uff08Title Reverse sort order\uff09", "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": {"sort_field": "title", "sort_order": "desc"}, "instruction_template": "\u5728Joplin\u4e2d\u5c06\u5f53\u524d\u7b14\u8bb0\u9875\u9762\u7684\u6392\u5e8f\u65b9\u5f0f\u4fee\u6539\u4e3a\u6807\u9898\u5012\u5e8f", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js"}, {"role": "handler", "path": "handler.py"}], "timeout": 30, "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\u5f53\u524d\u7b14\u8bb0\u9875\u9762\u7684\u6392\u5e8f\u65b9\u5f0f\u662f\u5426\u4e3a\u6807\u9898\u5012\u5e8f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u7b14\u8bb0\u6392\u5e8f\u65b9\u5f0f\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 插件 API 来处理通信
joplin.plugins.register({
    onStart: async function() {
        console.log('Joplin plugin started');
        // 监听 evaluate 事件
        socket.on("evaluate", async () => {
            console.log('Task19_sortNotesByTitleDesc---------------------------');
            try {
                // Joplin官方API没有直接获取当前排序方式的接口
                // 但可以通过settings获取相关设置
                let sortField = null;
                let sortOrder = null;
                try {
                    sortField = await joplin.settings.globalValue('notes.sortOrder.field');
                    sortOrder = await joplin.settings.globalValue('notes.sortOrder.reverse');
                } catch (e) {
                    // 某些Joplin版本可能没有这些设置
                    console.warn('无法通过settings获取排序方式:', e);
                }
                // 兼容Joplin的排序设置
                // sortField 可能为 'title', sortOrder 可能为 true(倒序) 或 false(正序)
                let sortFieldStr = sortField || 'unknown';
                let sortOrderStr = (sortOrder === true || sortOrder === 1 || sortOrder === '1') ? 'desc' : 'asc';
                // 使用 postMessage 发送评估消息
                window.postMessage({
                    "event_type": "evaluate_on_completion",
                    "message": `当前排序方式: 字段=${sortFieldStr}, 顺序=${sortOrderStr}`,
                    "data": {
                        "sort_field": sortFieldStr,
                        "sort_order": sortOrderStr
                    }
                }, '*');
            } catch (error) {
                console.error('Error in evaluate handler:', error);
                window.postMessage({
                    "event_type": "evaluate_on_completion",
                    "message": "无法获取当前排序方式，Joplin API未提供相关接口",
                    "data": {
                        "sort_field": "unknown",
                        "sort_order": "unknown"
                    }
                }, '*');
            }
        });
    }
}); 

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'))
    
    if event_type == "evaluate_on_completion":
        data = message.get("data", {})
        sort_field = data.get("sort_field")
        sort_order = data.get("sort_order")
        
        expected_field = task_parameter.get('sort_field', 'title')
        expected_order = task_parameter.get('sort_order', 'desc')
        
        logger.info(f"期望排序字段: {expected_field}, 期望排序方式: {expected_order}")
        logger.info(f"实际排序字段: {sort_field}, 实际排序方式: {sort_order}")
        
        if sort_field == expected_field and sort_order == expected_order:
            return [
                {"status": "key_step", "index": 1},
                {"status": "success", "reason": f"当前排序方式为：{sort_field} {sort_order}"}
            ]
        else:
            return [{"status": "error", "type": "evaluate_on_completion", 
                    "message": f"排序方式不匹配，期望：{expected_field} {expected_order}，实际：{sort_field} {sort_order}"}]
    return None