Files
skill-template/tools/ui_inspector/adapters/wecom.py
chendelian 633ecff4e2 chore: archive tools/ui_inspector snapshot before migration removal.
Keep the last in-template copy on main so history can restore it; product continues in jiangchang-ui-recorder.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 11:19:14 +08:00

104 lines
3.5 KiB
Python

"""WeCom (企业微信) adapter — profile / window / postcondition helpers."""
from __future__ import annotations
from typing import Any, Optional
from .registry import register_adapter
PROFILE_WECOM = "wecom"
PROFILE_WECOM_SEARCH = "wecom_search"
_THRESHOLDS = {
PROFILE_WECOM: 80,
PROFILE_WECOM_SEARCH: 20,
}
class WeComAdapter:
name = "wecom"
def matches(
self, *, class_name: str = "", title: str = "", process_name: str = ""
) -> bool:
return self.wake_profile(class_name=class_name, title=title) is not None or (
"WXWork" in (process_name or "")
)
def wake_profile(self, *, class_name: str = "", title: str = "") -> Optional[str]:
cls = (class_name or "").strip()
title = title or ""
if cls == "SearchResultWindow2":
return PROFILE_WECOM_SEARCH
if cls == "WeWorkWindow":
return PROFILE_WECOM
if "WeWork" in cls and (
"企业微信" in title or "WeCom" in title or "wecom" in title.lower()
):
return PROFILE_WECOM
return None
def cache_key(self, *, profile: str, hwnd: int = 0) -> str:
"""Separate main window vs SearchResultWindow2 warm caches."""
return f"{profile}:hwnd:{int(hwnd or 0)}"
def warm_threshold(self, profile: str) -> int:
return int(_THRESHOLDS.get(profile, 80))
def is_search_popup(self, *, class_name: str = "") -> bool:
return (class_name or "") == "SearchResultWindow2"
def is_main_window(self, *, class_name: str = "") -> bool:
return (class_name or "") == "WeWorkWindow"
def known_ids(self) -> dict[str, str]:
return {
"searchedit": "search_box",
"groupbuddyname": "contact_row_name",
"search_name": "search_result_name",
"send_rich_edit": "compose_box",
"panel_title_label": "panel_title",
}
def propose_postconditions(self, changes: list[dict[str, Any]]) -> list[dict[str, Any]]:
props: list[dict[str, Any]] = []
for ch in changes or []:
kind = ch.get("kind")
detail = ch.get("detail") or {}
if kind == "popup_disappeared" and "SearchResult" in str(
detail.get("class_name") or ""
):
props.append(
{
"description": "SearchResultWindow2 disappeared",
"kind": "window_absent",
"status": "proposed",
"detail": detail,
}
)
if kind == "element_appeared":
name = str(detail.get("name") or detail.get("automation_id") or "")
if name in {"send_rich_edit", "main_chattext", "panel_title_label"}:
props.append(
{
"description": f"WeCom element {name} appeared",
"kind": "element_present",
"status": "proposed",
"detail": detail,
}
)
if kind == "title_changed":
props.append(
{
"description": f"Chat title became {detail.get('to')!r}",
"kind": "title_equals",
"status": "proposed",
"detail": detail,
}
)
return props
wecom_adapter = WeComAdapter()
register_adapter(wecom_adapter)