Task configuration:
{"task_id": "20", "task_name": "\u521b\u5efa\u4e00\u4e2a\u53ebcs\u7684deck\uff0c\u5c06\u6240\u6709tag\u4e3acs\u7684\u5361\u7247\u79fb\u5165\u5230\u91cc\u9762\u53bb", "description": "\u521b\u5efa\u4e00\u4e2a\u53ebcs\u7684deck\uff0c\u5c06\u6240\u6709tag\u4e3acs\u7684\u5361\u7247\u79fb\u5165\u5230\u91cc\u9762\u53bb", "application_info": {"name": "anki", "executable_path": "/home/agent/anki/out/pyenv/bin/python", "args": ["/home/agent/anki/tools/run.py"], "cwd": "/home/agent/anki"}, "task_parameters": {"tag_name": "cs"}, "instruction_template": "\u521b\u5efa\u4e00\u4e2a\u53eb${tag_name}\u7684deck\uff0c\u5c06\u6240\u6709tag\u4e3a${tag_name}\u7684\u5361\u7247\u79fb\u5165\u5230\u91cc\u9762\u53bb", "evaluation_setup": {"scripts": [{"role": "hook", "path": "hooker.js", "dependency": ["../common/hooker_common.js"]}, {"role": "handler", "path": "handler.py"}], "timeout": 60, "evaluate_on_completion": true}, "events": {"add_deck": {"description": "\u6dfb\u52a0\u6210\u529f", "is_key_step": true, "key_step_index": 1, "key_step_name": "\u6dfb\u52a0\u6210\u529f"}, "move_card": {"description": "\u79fb\u52a8\u4e00\u4e2a\u5361\u7247", "is_key_step": true, "key_step_index": 2, "key_step_name": "\u79fb\u52a8\u4e00\u4e2a\u5361\u7247"}, "move_all_cards": {"description": "\u79fb\u52a8\u5b8c\u6240\u6709\u5361\u7247", "is_key_step": true, "key_step_index": 3, "key_step_name": "\u79fb\u52a8\u5b8c\u6240\u6709\u5361\u7247"}}, "sql_path": "/home/agent/.local/share/Anki2/sam/collection.anki2", "total_key_steps": 3, "mcp_servers": [{"command": "/home/agent/anki-mcp-server/.venv/bin/python", "args": ["/home/agent/anki-mcp-server/run_server.py"]}]}

Hook script:
const TRACE_FUNCTION = [
    "storage_add_deck",
    "storage_update_card"
]
function initHooks() {
    // iterate function name and addr, init it.
    for (const function_name of TRACE_FUNCTION){
        initHook(function_name, TRACE_MAPS[function_name]);
    }
}
initHooks();
sendLog("info", "add hooks done");

Evaluation handler:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import os
sys.path.append(os.path.dirname(__file__))
from common import *

def handle_storage_add_deck(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    decks : List[int] = list(filter(lambda deck:deck.name == tp.tag_name,context.decks))
    if len(decks):
        deck = decks[0]
        cards :List[Card] = list(filter(lambda c:tp.tag_name in c.get_note().tags,AnkiObjMap().array_by_type("card")))
        context._this_did = deck.did
        context._number_of_card_with_tag = len(cards)
        context._counter = 0
        status.emit(EventAddDeck())
    return status

def handle_storage_update_card(context: Context,message) -> Status:
    context.update_database()
    status = Status()
    card : Card = sorted(AnkiObjMap().array_by_type("card"),key=lambda x: x.mod,reverse=True)[0]
    did : List[int] = list(map(lambda deck:deck.did,filter(lambda deck:deck.name == tp.tag_name,context.decks)))
    if not did:
        return status
    did = did[0]
    if tp.tag_name in card.get_note().tags and did == card.did:
        context._counter += 1
        if context._counter == context._number_of_card_with_tag:
            status.emit(EventMoveAllCards())
        else:
            status.emit(EventMoveCard())
            status.mark_progress()
    return status

def handle_done(context: Context,message) -> Status:
    status = Status()
    if not context.monitor.is_event_triggered(EventAddDeck()):
        status2 = handle_storage_add_deck(context,message)
        context.trigger_event_immediately(status2.metric)
        status.metric.extend(status2.metric)
        
    if not context.monitor.is_event_triggered(EventMoveAllCards()):
        context.update_database()
        cards : List[Card] = list(filter(lambda c:tp.tag_name in c.get_note().tags,AnkiObjMap().array_by_type("card")))
        if all([c.did == context._this_did for c in cards]):
            status.emit(EventMoveCard())
            status.emit(EventMoveAllCards())
    return status
        
TRACE_HANDLERS = {
    "storage_add_deck": handle_storage_add_deck,
    "storage_update_card": handle_storage_update_card,
}   
dependency_graph = {
    add_deck_: [],
    move_card_: [],
    move_all_cards_ : [move_card_]
}
finished_list = [
    move_all_cards_
]

bind_handlers(TRACE_HANDLERS,dependency_graph,finished_list,done=handle_done)