WorkBuddy 自动签到

SKILLAI 工具
AI 工具 未标注权限 许可证不明确
安装这个技能

当用户需要在 Windows 上运行、维护、校准或自动化 WorkBuddy 每日签到/积分领取时使用此技能。二级降级:UIA 无障碍树优先、OCR 图像识别兜底,均后台静默(不动鼠标、不抢前台、不依赖硬编码坐标)。用户名/窗口标题/按钮关键词/锚点偏移等均通过 scripts/config.json 配置,可移植到其他机器。

一句话选型结论

按资料字段整理

WorkBuddy 自动签到是AI 工具类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类AI 工具 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_7c33246a/workbuddy-auto-checkin
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

AI 工具
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_7c33246a仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791736299
正文体量34.4 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
组合多个 AI 能力

把写作、检索、总结串成一条流程。

搭工作流

把固定流程做成可重复调用的步骤。

做提示词与评测

整理提示词并对比输出效果。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在AI 工具场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
WorkBuddy 自动签到当前 未标注权限 未标注 未标注 未标注 有
执行计划 只读 GitHub 仓库 151.5 万 Codex、Claude、Cursor 有
Playwright MCP 测试 浏览器控制 ClawHub 市场 136.5 万 OpenClaw 有
完成前的验证 未标注权限 GitHub 仓库 131.9 万 Codex、Claude、Cursor 有
子 Agent 驱动开发 只读 GitHub 仓库 131.2 万 Codex、Claude、Cursor 有
前端设计 执行命令 GitHub 仓库 125.6 万 Codex、Claude、Cursor 有

SKILL.md 全文

34.4 KB
模型实际读到的说明书原文,来自技能仓库

WorkBuddy 每日签到(二级降级:UIA → OCR)

用途

在 Windows 上自动完成 WorkBuddy 每日签到/积分领取。完全后台静默——不动用户
真实鼠标、不抢前台焦点、不闪屏、不依赖硬编码屏幕坐标。

WorkBuddy v5.4.7(2026-09-01 实测,当前版本)的签到是三步流程:

> 版本注意:v5.4.5 曾因 Electron 37 / Chromium 138 的无障碍树渲染问题导致 UIA 失效
> (renderer accessibility tree 不渲染,只剩空 Pane);v5.4.7 已修复,UIA 三步恢复走通。
> 但入口按钮文案同步改版:「签到领积分」被移除,改为「Buddy加油站」(详见 v9/v10 段)。
> 当前 UIA(L1 主方案)与 OCR(L2 兜底)两级均可用,UIA 优先。

  1. 点头像(左下角用户头像)→ 弹出用户菜单;
  2. 点菜单里的「Buddy 加油站」入口 → 打开加油站卡片;
  3. 点卡片里的「立即领取 / 今日已领」→ 完成签到。

方案:二级降级(scripts/check_in.py 总调度)

层级 脚本 定位方式 适用
L1 主方案 uia_checkin.py UIA 无障碍树 InvokePattern 应用暴露 a11y 树(Electron 默认)
L2 兜底 ocr_checkin.py 截屏 + RapidOCR 文字定位(文字优先,头像用圆检测识别) UIA 拿不到元素时(游戏/自绘 UI)

纯坐标版已删除(分辨率/DPI/窗口/改版任一变化即失效)。v15 起 L2 进一步去坐标化:
入口定位一律以「OCR 认出文字」为成功判据,头像靠圆检测识别图标,坐标只在运行时动态计算、
绝不落盘——详见下方 L2 章节。

运行:

# 用本机 WorkBuddy 托管 Python 执行(路径按实际安装位置替换 <USERPROFILE> 与 skill 目录)
& "<USERPROFILE>\.workbuddy\binaries\python\envs\default\Scripts\python.exe" "<skill目录>\workbuddy-check-in\scripts\check_in.py"

check_in.py 自动降级:先跑 UIA,失败(非 0 或异常)自动切 OCR。也可单独指定
--uia / --ocr。

判定输出:[3] 按钮: '立即领取' = 本次签到成功;[3] 按钮: '今日已领' = 当日已签过。

L1:UIA 方案要点(uia_checkin.py)

  • 用 pywinauto 对每个按钮调用 InvokePattern(系统无障碍层点击),不依赖坐标。
  • ensure_window_state:仅在「隐藏/最小化」时 SW_SHOWNOACTIVATE 恢复显示(不激活、不抢前台),不再强制最大化。
  • warmup:预热 UIA 树(Electron 无障碍树懒加载,首次访问可能为空,重试)。
  • close_popups:归一化——关残留卡片 + ESC。
  • 关键词与窗口标题统一从 scripts/config.json 读取(avatar_name=头像用户名、
    uia.entry_keywords=「签到领积分」入口、uia.claim_keywords/claimed_keywords=
    领取按钮),不再硬编码在脚本里。

L2:OCR 方案要点(ocr_checkin.py)

  • 截图:PrintWindow(hwnd, PW_RENDERFULLCONTENT) 截窗口客户区内容(后台可截,
    即使被游戏全屏遮挡也能截到 Chromium GPU 合成完整内容),ctypes GDI GetDIBits 读回
    numpy BGR。不依赖窗口最大化/置顶/屏幕位置。
  • 坐标系:全部使用「窗口客户区相对坐标」(GetClientRect 取客户区尺寸),运行时动态计算,
    不落盘、不记忆任何绝对坐标——skill 会装在很多台各不相同的电脑上(窗口尺寸/DPI/版本各异),
    写死的坐标迟早是错的。对窗口位置/大小/状态完全无要求:随便拖、随便缩、被全屏遮挡都能工作。
  • 入口定位:三条路依次尝试,成功判据一律是「OCR 识别到入口文字」(不是坐标命中):
    1. 文字优先(open_entry 第一步):先纯 OCR 在左下角找「Buddy加油站」——
    菜单本就可见时零点击直达,彻底绕开坐标;
    2. 头像识别(find_avatar,路 2):菜单不可见时,用圆检测 HoughCircles 在左下角
    识别头像圆形图标、点其圆心开菜单。这是「认图」不是「认坐标」,跨 DPI/窗口尺寸自适应;
    实测 4 组参数都精确命中同一圆心(与 UIA 实测头像中心仅差 1px);
    3. 动态兜底(avatar_candidates,路 3):圆检测失败时,按「固定偏移×DPI 缩放 → 原始像素
    → 比例锚点 → 左下角内缩」算种子点,再以小网格围绕首个有效种子扩散,逐个尝试;
    网格永远围绕最可能的点展开,即使配置的偏移完全不对也还有邻近点可试(实测:偏移写错
    时自动纠偏到正确位置)。全部候选限制在左下角区域内,避免误点侧栏。
  • 按钮定位:在客户区左下角 400×700 子区域 OCR 识别「Buddy加油站」「立即领取」「今日已领」
    等文字,返回客户区相对坐标。
  • 点击:PostMessage 客户区坐标 lp=(y<<16)|x(已经是客户区坐标,不需要 ScreenToClient),
    后台静默。每点一次头像都会 OCR 复验入口是否出现,未出现就 ESC 关掉浮层再试下一个。
  • 单次 OCR 约 1.7s;三步总耗时约 10~20s。
  • 关卡片(v16):走完三步后调 close_card(hwnd) 收掉加油站卡片——L1 UIA
    InvokePattern 点「关闭…加油站」按钮(认按钮不认坐标),L2 ESC 兜底。
    注:ESC 本身无效(已实测 PostMessage/SendMessage 三种发法全失败,因窗口被
    disable_activate 置为不可激活时 Chromium 丢弃按键消息),故 L1 才是真正起作用那层。
    整个函数 best-effort,失败不影响签到结果。
  • 已知局限:OCR 偶发识别偏差(如「已领3天」→「已领3天1」),不影响按钮定位。
  • 实测(2026-09-12):check_in.py --ocr 全流程跑通,日志见「头像识别:圆检测命中头像 @ (35,889)
    → 入口 OCR 命中 'Buddy加油站' → 按钮 OCR 命中 '今日已领' → 退出码 0」。

依赖

方案 依赖 是否必需
L1 UIA pywinauto(纯 Python + comtypes,约几 MB) 必需
L2 OCR rapidocr-onnxruntime + onnxruntime + numpy(约 100MB) 可选(仅 OCR 兜底需要)

rapidocr 在 ocr_checkin.py 内延迟导入——只用 UIA 方案时,OCR 那套约 100MB
的依赖(rapidocr/onnxruntime/opencv)无需安装。安装命令(在托管 venv 内):

# 仅 UIA(最小安装)
& "<USERPROFILE>\.workbuddy\binaries\python\envs\default\Scripts\pip.exe" install pywinauto

# 需要 OCR 兜底时再补装(约 100MB)
& "<USERPROFILE>\.workbuddy\binaries\python\envs\default\Scripts\pip.exe" install rapidocr-onnxruntime "onnxruntime==1.20.1"

> 注意:onnxruntime 需锁 1.20.1——1.28.0 在 Python 3.13 下 DLL 初始化失败。

配置(scripts/config.json)

所有可移植参数集中在 scripts/config.json,移植到新机器/新账号只改配置、不改代码:

配置项 含义 默认值
window_title WorkBuddy 窗口标题 WorkBuddy
avatar_name 头像/账号用户名(UIA 定位头像用) 必填:填 WorkBuddy 左下角显示的账号名(留空则跳过 UIA、自动走 OCR)
report_path 签到成功后的周汇总记录路径(可选,市场用户留空) ""(空)
uia.entry_keywords 加油站入口按钮关键词 ["Buddy加油站"]
uia.claim_keywords / claimed_keywords 领取/已领按钮关键词 ["立即领取"] / ["今日已领"]
uia.entry_click_offset.fx/fy 复合入口按钮点击偏移 0.3 / 0.26
ocr.entry_keywords 等 OCR 定位关键词(入口优先,含「Buddy加油站」「加油站」) 见 config.json
ocr.avatar_detect.* 路2 圆检测:头像识别区域/半径范围(左下角) 360×160 / r10~26
ocr.avatar_anchor.* 路3 动态兜底种子:offset_x/y(像素)、fx/fy(比例)、box_*(限制区)、grid_step、max_attempts 94/34、0.10/0.037 等
ocr.scan.width/height OCR 扫描子区域 400 / 700
ocr.card_close.close_keywords / require 关卡片时匹配的按钮名(须同时含 close_keywords 各项 + require) ["关闭"] / 加油站

> 不落盘原则:以上坐标类参数只在运行时参与计算,脚本不记忆、不落盘任何绝对坐标
> (跨机器存坐标本身是隐患)。所以 state 文件里只有 last_checkin_date/time。

加载优先级:环境变量 WB_CHECKIN_CONFIG 指定文件 > 同目录 config.json > 内置默认值。
缺失项自动回退默认值,配置文件损坏只打印提示、不中断签到。

与上游版本的差异(重要——请勿静默回滚)

  • v17(2026-09-12 发布 v1.12.0 前的上架整理)——去本机化,让发布包可被任何人直接用:
  • 配置默认值去硬编码:config.py 的 _DEFAULTS["avatar_name"] 由固定的本机账号名
    改为空字符串(并在注释与文档中标注「必填」)。留空时 UIA 会跳过头像定位、自动降级
    OCR,不会崩;填对自己的账号名则走最快的 UIA 路径。
  • report_path 默认留空:这是「签到成功后追加一条记录到你自己的文件」的可选功能,
    属本机自用,发布包中一律留空(不写任何文件);本机自用值只在本地配置里。
  • 文档去本机化:SKILL.md / README.md / references 中的本机绝对路径、本机 automation
    ID、账号名等一律替换为占位符或通用描述(沿用 1.10 发布时确立的同一条标准)。
  • 发布包清理:排除 __pycache__ 等字节码缓存。
  • 功能上零行为变更(除"未配置 avatar_name 时降级 OCR"这一更安全的默认),v12–v16
    的全部改造随本版本一并首次上架。

  • v16(2026-09-12 用户追问「关窗口有没有同步到 OCR 侧和挂起的那份」)——
    OCR 侧关卡片修复:ESC 根本无效,改为「认按钮不认坐标」:

  • 实测发现(重要):v13 给 OCR 侧加的「发 ESC 关卡片」从未生效。实测卡片开着时,
    PostMessage ESC(lParam=0)、PostMessage ESC(带扫描码)、SendMessage ESC(带扫描码)
    三种发法全部失败(卡片仍在);只有点真正的「关闭 Buddy 加油站」按钮才关得掉。
    根因:脚本全程 disable_activate(WS_EX_NOACTIVATE),Chromium 在无焦点时不处理按键消息。
    → 用户此前反馈「每次都要手动关掉」,OCR 兜底路径就是元凶。
  • 改造:close_card(hwnd) 分层 best-effort——
    L1 _close_via_uia():用 UIA InvokePattern(el.invoke())点「关闭…加油站」按钮,
    完全不用任何像素坐标;L2 close_popups():ESC 兜底(可能无效但无害)。
    整个 close_card 外层包 try/except,失败绝不冒泡、绝不影响签到结果判定。
  • 刻意不做图像点击:实测用「亮色卡片右上角内缩」推算 ✕ 也准(推算 (232,652) vs 真值
    (230,650),仅差 2px,4 个阈值下都稳定),但故意未采用——关卡片只是外观锦上添花,
    而图像点击在暗色主题下可能误判亮区、点到侧栏条目(有副作用)。规避 > 补救:宁可不做。
  • 回退路径同步受益:check_in.py 只是调度壳,close_popups()/close_card() 仅存在于
    ocr_checkin.py,故在用版与被挂起的旧 automation 版共用同一处,修一次两边都好。
  • 配置新增 ocr.card_close: {close_keywords, require}(默认 ["关闭"] + 加油站)。
  • 实测:check_in.py --ocr 从「卡片关闭」起点走完整流程 → 退出码 0 → 卡片已关闭
    (UIA 探测「加油站」相关按钮为空);check_in.py 默认 UIA 路径无回归。
    单元测试 4 项全 PASS(UIA 不可用走 ESC、UIA 可用不调 ESC、两级都抛异常不冒泡、
    卡片未开时安全返回 False)。

  • v15(2026-09-12 用户反馈「别的机器上出现坐标不匹配,当时靠看菜单文字才对」)——
    OCR 定位去坐标化(认字 + 认图,不认死坐标):

  • 背景:ocr_checkin.py 原来靠「头像固定像素偏移 (102,42)」点头像开菜单。实测本机真实
    头像在 (94,34)(MenuItem 中心)/ 圆检测 (35,889),配置值已偏 8~10px——本机因 MenuItem
    够宽(164×44)侥幸命中,换窗口尺寸/DPI 必漏。用户定调:skill 装在很多台各不相同的电脑上,
    不要存绝对坐标,要动态、要稳
    。
  • 改造:入口定位改为三路并行,成功判据一律是 OCR 识别到入口文字——
    ①文字优先:先纯 OCR 找「Buddy加油站」,菜单可见时零点击直达;
    ②头像识别:find_avatar() 用 HoughCircles 圆检测识别头像圆形图标,点圆心开菜单
    (认图不认坐标;实测 4 组参数均精确命中同一圆心);
    ③动态兜底:avatar_candidates() 按「偏移×DPI → 原始像素 → 比例锚点 → 左下角内缩」
    算种子,再以网格围绕首个有效种子扩散;即使配置偏移全错也能自动纠偏。
  • 不落盘:彻底不做坐标记忆/Persistence(曾短暂实现 ocr_avatar_hit 自校准,经用户
    指正后移除——跨机器存坐标本身就是隐患)。每次运行全部重新动态计算,state 文件里
    只剩 last_checkin_date/time。
  • 配置新增 ocr.avatar_detect(圆检测区域/半径范围)与 ocr.avatar_anchor 的
    fx/fy/box_width/box_height/grid_step/max_attempts;entry_keywords 补「加油站」。
  • 实测:check_in.py --ocr 全流程跑通(圆检测命中头像 → 入口文字命中 → 按钮「今日已领」→
    退出码 0);候选点单元测试覆盖 4 种窗口尺寸/DPI 与「偏移写错」场景,均在框内且能纠偏。
  • 回退路径同步受益:check_in.py 只是 10 行调度壳,坐标逻辑仅存在于 ocr_checkin.py,
    所以在用版(v2)与被挂起的回退版(旧 automation → check_in.py)共用同一处,修一次两边都好。

  • v14(2026-09-12 用户定调「排障可读性不可牺牲,噪音会磨损判断力」)——日志改造 + 自熄降级:

  • 日志契约(硬规则):
    • 例行动作不写日志:标志位命中秒退 → 零输出(原先每小时写一条「熄火失败」已消除)。
    • 同一类异常每天最多一条(_log_daily_once),杜绝例行失败刷屏淹没信号。
    • 真实事件每次必写:签到闭环(含方案 + 耗时)、签到未完成、周汇总写入、一次性状态变更。
    • --debug:输出全量细节(含例行动作),排障时随要随有——可读性与可调试性二者兼得。
    • 硬契约:某天完全没有日志 = 异常信号(任务没跑 / 一直没签成功),应主动排查。
    • 日志自动轮转:超过 256 KB 归档为 workbuddy-check-in.log.1,不无限增长。
  • 自熄改为「尽力而为 + 一次说明 + 永久停用」:_silence_today() 首次遇权限失败时,把状态
    标记为 selfextinguish: unsupported 并只写一条说明,此后静默返回(不再每次 spawn
    schtasks 徒劳尝试
    、不再刷屏)。降级态 = 「每小时唤醒 + 标志位静默秒退」,用户无感。
  • 取舍依据(重要):不为「感知不到的零唤醒」给签到脚本提权。规避 > 监控——不让需要
    特权的操作进循环,风险面直接归零;若日后确需真·零唤醒,另择无特权路径(如按用户级启动项
    • 常驻监督进程 + 每日心跳),不采用提权方案。
  • 实测:秒退路径 0 日志(--debug 1 行);自熄失败 1 行说明 + 置 unsupported,二次调用 0 日志
    0 次 schtasks 调用;完整流程 2 行高信号日志(签到闭环 + 周汇总)。

  • v13(2026-09-12 用户要求「签到完成后把加油站小窗口也关掉」)——签到后收拾现场:

  • 关窗口:uia_checkin.py 在「三步流程跑完」后调用 close_popups(connect()) 关闭加油站
    卡片(点「关闭 Buddy 加油站」按钮 + ESC 兜底);ocr_checkin.py 走完后 → ⚠️ 原为
    close_popups()(仅 ESC),实测该 ESC 从未生效,已于 v16 改为「UIA 按钮优先 + ESC 兜底」
    的 close_card()
    。关闭失败吞异常、不影响签到结果判定。实测 UIA 路径卡片成功关闭
    (探测无「关闭 / 今日已领 / 立即领取」残留按钮)。
  • ⚠️ 发现「自熄闹钟」失效(已于 v14 定案处理):计划任务 WorkBuddyCheckIn 的 RunLevel 是
    LeastPrivilege(普通权限),脚本在任务上下文里执行 schtasks /change 改触发时间时报
    「请输入 Administrator 的密码」(需管理员权限),故从 2026-09-10 起熄火一直失败,任务
    StartBoundary 停在 09-10 06:00,退化为「每小时唤醒 + 标志位秒退」。v14 定案:不做提权
    修复
    (为感知不到的零唤醒付安全代价不划算,且提权方案在 AI 侧无法验证、对市场用户需一次性
    管理员操作);改为「尽力而为 + 一次说明 + 永久停用」,并把日志改造成高信噪比台账。

  • v12(2026-09-09 用户明确「skill 上架市场、他人也在用,须通用、不能依赖本机 automation」)——
    调度做进程序:Windows 计划任务 + 自举注册 + 成功自熄闹钟(check_in_v2.py 升级)。

  • 背景:有反馈「automation 改不了」,市场用户装 skill 拿不到本机 automation;且用户要
    「签过一次后,当天连唤醒都不跑」。故把每日签到调度从 WorkBuddy automation 移到 skill 程序内。
  • 三件套:
    1. 自举注册:每次运行幂等检查计划任务 WorkBuddyCheckIn 是否存在,不存在则用
      sys.executable(pythonw.exe)+ __file__ 动态 schtasks /create /sc hourly /mo 1 注册
      ——市场用户装哪儿都能用、零手动、重启不失效(任务计划是系统持久配置)。
    2. 前置标志位门禁:读 ~/.workbuddy/state/workbuddy-check-in.json,已签秒退。
    3. 成功自熄闹钟:签到成功(退出码 0)后 schtasks /change /sd 明天 /st 06:00,把任务
      推迟到次日 06:00——当天剩余整点零唤醒、零打扰,次日 06:00 自动恢复每小时唤醒。
  • 可选用「周汇总记录」:report_path(环境变量 WB_CHECKIN_REPORT 或 config.json 的
    report_path 字段)非空时,签到成功追加一条 memory.md 兼容记录(含「成功」+「UIA/OCR 降级」),
    供周汇总统计;市场用户留空即不落盘。
  • 回滚:本机原有的「每天 10:00」旧 automation 继续 PAUSED 作回退;验证期间临时建的
    「每小时」automation(本机配置,市场用户拿不到)已删除。
  • 踩坑:schtasks 在中文 Windows 输出 GBK,subprocess 不能用 text=True(UTF-8 解码报
    UnicodeDecodeError、reader 线程抛 traceback)——改为 capture_output=True 取字节,再
    UTF-8→GBK→replace 兜底解码。
  • 验证:2026-09-09 注册 WorkBuddyCheckIn(每小时、交互式、已启用),熄火后下次运行
    2026-09-10 06:00;--force 全流程 UIA 命中「今日已领」+ 报告写入正确。

  • v11(2026-09-09 用户提出「每小时触发 + 标志位」改造)——新增隔离版 check_in_v2.py:

  • 动机:用户「到公司时间不固定、常早于常规」,单点定时(10:00)会漏签(如 8/30 周末)。
    想要「每小时触发 + 签过一次后后续全部跳过」。
  • 核心:前置标志位门禁。脚本一进来先读「今日已签」标志位
    (~/.workbuddy/state/workbuddy-check-in.json,last_checkin_date)——已签则毫秒级秒退
    (实测 0.144s),不 import pywinauto、不碰窗口、不做 UIA/OCR;未签才复用 check_in.main()
    二级降级,退出码 0 时原子写标志位。支持 --force 忽略标志位强制重跑(纠正误写用)。
  • 隔离 + 灰度:新脚本独立于 check_in.py,二者并存。当时旧调度(每天 10:00,指向
    check_in.py)已暂停保留作回退;验证期间的「每小时」触发先小范围灰度,跑稳后再切换。
    该灰度已结束——v12 起调度改由程序内自举注册计划任务承担(见下)。
  • 调度器限制(重要):BYHOUR 只接受单个整数、不支持逗号分隔多值(BYHOUR=6,10 实测报错),
    故「5-23 点每整点」表达不了,改用 FREQ=HOURLY;INTERVAL=1(每小时,凌晨靠「用户不开机」自然不触发)。

  • v10(2026-09-01 二次排查)——WorkBuddy 5.4.7 修复无障碍树 + 入口文案改版:

  • 5.4.7 修复了 5.4.5 的无障碍树渲染 bug:UIA 树从「9 个空 Pane」恢复为丰满
    (358 个非空 name 元素,含 Image/Button/Text/MenuItem)。UIA 三步重新走通,不再降级 OCR。
  • 入口文案改版:点头像后的用户菜单里,加油站入口按钮名称从
    'Buddy 加油站 签到领积分 去邀约 最高得 650 积分/人'(三行)变为
    'Buddy加油站 去邀约 最高得 650 积分/人'(两行,去掉了「签到领积分」)。
  • 修补:config.json 与 config.py 的 uia.entry_keywords 由 ["签到领积分"] 改为
    ["Buddy加油站"](无空格,精确命中入口且不会误匹配「关闭 Buddy 加油站」)。
  • 偏移无需改:新入口按钮 rect (30,863)-(336,951) 306x88,子元素 Text 'Buddy加油站'
    位于 y 874~895(相对 fy≈0.24)、x 64~157(相对 fx≈0.26),与现有 fx=0.3, fy=0.26 吻合。
  • v9 的空树快速失败逻辑保留有效:树丰满(>50)时正常走 UIA,树为空时(未来某版本
    又回归)快速降级 OCR。两层防御互不冲突。
  • 验证:2026-09-01 10:3x 跑通 UIA 三步:[1] 头像 '<用户名> <用户名>' → [2] 入口 'Buddy加油站 去邀约 最高得 650 积分/人' → [3] 按钮 '今日已领' → === 三步流程跑完 ===。
  • v9(2026-09-01)——WorkBuddy 5.3.12 → 5.4.5 升级后 UIA 事实上不可用,精准快速失败:
  • 根因:WorkBuddy 升级到 5.4.5(Electron 37.10.3 / Chromium 138.0.7204.251)。
    Chromium 130+ 在 Windows 上改了无障碍行为:没有真实 AT(Narrator/读屏)客户端时,
    Chromium 不再渲染 renderer accessibility tree——UIA 树只剩 browser-side 一串空 Pane,
    无任何 Button/Image/MenuItem/Text 元素。pywinauto 触发不了(实测:UIA 树只有 9 个空 Pane;
    即使 SetForegroundWindow 强制激活窗口、或发 WM_GETOBJECT(OBJID_CLIENT) 反复触发,元素数都 < 50)。
  • 触发场景:新版本 WorkBuddy 用户。
  • 修补:
    1. warmup() 的"树丰满"判定阈值从 n &gt; 10 提到 n &gt; 50(老版本 Electron 25/26 丰满时通常
      100~300+,50 是安全的"有 vs 无"分界)。
    2. main() 开头加二次检测:descendants &lt; 50 立即 print 明确诊断日志
      (FAIL: UIA 树为空(descendants=N &lt; 50),疑似 Electron 37+/Chromium 130+ 默认禁用 renderer 无障碍树;强制降级 OCR)并 return 1,让总调度切 OCR 兜底。
    3. 旧 warmup 重试间隔从 0.5s 缩到 0.3s,整体 UIA 失败判定耗时 ≈ 1.5s(原本浪费 2.5s
      warmup + close_popups + find avatar 一连串失败才退出)。
  • 保留 UIA 方案的代码不动:仅改阈值。如果未来 Electron 修复了无障碍或 WorkBuddy
    启动时加 --force-renderer-accessibility,UIA 层仍能立即恢复,不需重写。
  • 影响:当前签到实质上 = OCR 方案在跑,UIA 是"等老版本回来"的兜底。
    总签到时间从 ~12s 缩到 ~9s(UIA 阶段少 3.5s)。
  • 验证:2026-09-01 跑通:UIA 1.5s 内 fail + 明确诊断 → OCR 三步全中 → 按钮「今日已领」
    判定成功。
  • 未来彻底恢复 UIA 的可能路径(未实施):
    1. 让 WorkBuddy 启动时带 --force-renderer-accessibility(需修改 WorkBuddy 启动快捷方式/脚本,超出本 skill 范围);
    2. 临时 SystemParametersInfo(SPI_SETSCREENREADER, TRUE) 让 Chromium 检测到屏幕阅读器
      标志(副作用大,不推荐);
    3. 等 Chromium 上游修复无障碍默认行为。
  • v8(2026-08-19)——彻底消除抢前台(用户反馈"今天没全屏也抢"后实测定位):
    1. 抢前台元凶 = el.invoke()(UIA IUIAutomationInvokePattern::Invoke)——
    Electron/Chromium 处理无障碍 invoke 时会激活窗口(系统层行为,跟是否
    最大化无关)。v6 只删了 SW_MAXIMIZE 和 click_input,漏了这个更隐蔽的源。
    2. 点击改用「UIA 拿元素坐标 + PostMessage 客户区点击」——
    新增 click(el, hwnd, fx, fy):拿 el.rectangle() 屏幕坐标 → ScreenToClient
    客户区 → PostMessage(WM_LBUTTONDOWN/UP)。完全不动鼠标、不激活窗口。
    Electron 响应 PostMessage 鼠标消息(OCR 方案早就验证过)。
    3. 全程加 WS_EX_NOACTIVATE 防护——Electron 弹浮层(点头像弹用户菜单)
    时会自我激活窗口,加这个 EXSTYLE 让 Windows 拒绝激活它。两级方案(UIA/OCR)
    都在 main() 开头 disable_activate、finally 里 restore_activate。
    4. click 支持 fx/fy 偏移——UIA 把三行菜单项「Buddy加油站」「去邀约」
    「积分余额」合并报成一个 Button(名称是拼接文字),rect 高 88px 覆盖三行,
    几何中心落在「去邀约」行(点中心 = 点去邀约,签到永远 FAIL)。入口
    点击改用 fx=0.3, fy=0.26(对齐「Buddy加油站」行,与 OCR 命中位置吻合)。
    5. 删 invoke()——被 click() 全面替代。close_popups 也用 click 关闭残留卡片。
    端到端验证:UIA 三步走通(不再降级 OCR),全程 137 次前台采样 0 次被 WorkBuddy 抢。
  • v7(2026-08-18)——OCR 也彻底去掉「最大化」依赖(用户洞察:窗口本身窗口化就能工作):
    1. 截图改用 PrintWindow 截窗口客户区——PW_RENDERFULLCONTENT 能截到 Chromium
    GPU 合成完整内容,即使被游戏全屏遮挡也能截到(实测窗口化状态 99% 非黑)。
    2. 坐标全转「客户区相对」——删除屏幕绝对区域 REGION=(0,780,360,660) 硬编码和
    GetWindowRect 锚点;扫描区域改为 GetClientRect 动态算的左下角 400×700。
    3. click_screen → click_client——PostMessage 客户区坐标,不需要 ScreenToClient。
    4. ensure_window 简化——只处理隐藏/最小化(SW_SHOWNOACTIVATE),不再
    SetWindowPos 铺满。OCR 完全不依赖窗口最大化/置顶/屏幕位置。
    原理:UIA 读树只需要窗口可见状态(被遮挡也行),不需要最大化;OCR 用 PrintWindow 截
    窗口内容同样不需要窗口最大化/置顶——用户的窗口本身是窗口化就能正常工作。
  • v6(2026-08-18)——修复「抢前台」打扰用户(玩游戏/全屏场景):
    1. 删 SW_MAXIMIZE——ShowWindow(SW_MAXIMIZE) 会激活窗口、抢焦点。
    UIA 读树根本不需要最大化:ensure_window_state 改为仅在「隐藏/最小化」时
    SW_SHOWNOACTIVATE 恢复显示(显示但不激活、不抢前台)。
    2. OCR ensure_window 铺满改用 SetWindowPos + SWP_NOACTIVATE | SWP_SHOWWINDOW,
    HWND_NOTOPMOST 不置顶遮挡前台应用,SPI_GETWORKAREA 取工作区尺寸,
    全程不激活窗口。
    3. 删除三处 click_input() 兜底——invoke 失败直接返回失败/降级 OCR,
    不再真实移动鼠标抢前台。
  • v5(2026-08-17):
    1. GetCurrentThreadId 移到 kernel32——v4 restore_foreground 用
    AttachThreadInput + SetForegroundWindow 时把 GetCurrentThreadId 错误挂在
    user32(实际属于 kernel32.dll),导致模块级 restype 赋值就抛
    AttributeError: function &#x27;GetCurrentThreadId&#x27; not found,两级方案全挂。
    修:顶部加 kernel32 = ctypes.windll.kernel32,.restype 与调用都改
    kernel32.GetCurrentThreadId。
    2. ensure_window_state / ensure_window 处理隐藏窗口——v4 只判 IsIconic,
    不处理 IsWindowVisible=False(用户关到系统托盘时常见)。
    3. 隐藏窗口先 SW_SHOWNOACTIVATE 再 SW_MAXIMIZE——直接 SW_MAXIMIZE 从
    隐藏态不会触发 Chromium 渲染 UIA 树(只剩 8 个 Pane),必须先 SW_SHOW 让
    窗口可见、Chromium 初始化 UIA 元素,再最大化。
  • v4:修复窗口抢前台——type_keys(&quot;{ESC}&quot;)(会 set_focus 激活窗口)改
    PostMessage 发 ESC;keybd_event 全局 ESC 改 PostMessage;脚本开头记录用户
    当前前台窗口(GetForegroundWindow),结束时用 AttachThreadInput + SetForegroundWindow
    原样归还(try/finally,成功失败都还)。v4 的 restore_foreground 框架正确,
    但 GetCurrentThreadId 挂错 DLL 由 v5 修正。
  • v3:二级降级 UIA → OCR,删除坐标版。
  • v2 delta:UIA Invoke 三步(替代坐标点击)。
  • v1 delta:PostMessage 替代 mouse_event、去前台抢占、加 IsIconic、修路径。
  • frontmatter / _meta.json 标 userModified: true,上游静默覆盖时可识别。

如果上游有新版本,按 open-plugin-vetting 流程选择性合并我们的 delta,不要整包替换。

自动化

  • 调度做进程序(v12 起):check_in_v2.py 自举注册 Windows 计划任务
    WorkBuddyCheckIn(每小时触发)。签到成功后尽力自熄到次日 06:00;该操作需管理员权限,
    不可用时自动永久停用并只说明一次(见 v14),降级为「每小时唤醒 + 标志位静默秒退」
    (约 0.3s、无窗口、不写日志、用户无感)。每日签到不依赖 WorkBuddy automation——
    automation 是本机配置,市场用户装 skill 时拿不到;计划任务由脚本自己注册,装哪儿都能用。
  • 可选的记录文件:config.json 的 report_path 非空时(或环境变量 WB_CHECKIN_REPORT
    覆盖),签到成功会向该文件追加一条记录,便于做你自己的签到/汇总统计。留空则不写任何文件。
  • 本机自用配置不进发布包:个人记录路径、本机 automation 等只存在于本机配置中。

日志与排障(v14 契约)

日志:~/.workbuddy/state/workbuddy-check-in.log 状态:~/.workbuddy/state/workbuddy-check-in.json

设计原则:日志是判断力的输入,信噪比优先。 例行动作不写日志,只有真实事件才写。

情形 是否写日志 说明
标志位命中、秒退 否 例行动作;每天可能发生 10+ 次,写就是噪音
签到闭环成功 是(1 行) 含方案(UIA/OCR 是否降级)+ 耗时
签到未完成(退出码非 0) 是 真正的信号:按计划每小时重试,持续出现即需排查
周汇总记录写入 是 每次成功签到一条
自熄不可用 仅一次 说明后置 selfextinguish: unsupported,永久停用
同上类异常(注册失败等) 每天最多一条 _log_daily_once 防刷屏
需要全量细节 --debug 例行动作也会记,排障时随要随有

⚠️ 硬契约:某天完全没有日志 = 异常信号。 正常情况下每天至少 1 行(签到闭环)。
若某天空白,说明「任务没跑」或「一直没签成功」,应主动排查,不要当成"没事"。

正常日志长这样(一天 1–2 行):

2026-09-12 11:38:14 [checkin] 签到闭环:方案 UIA(未降级),耗时 21.1s,退出码 0
2026-09-12 11:38:14 [report] 已写记录 → &lt;你的 report_path&gt;

排障常用命令:

# 看最近日志
tail -20 ~/.workbuddy/state/workbuddy-check-in.log
# 强制跑完整流程 + 全量日志(不碰计划任务、报告写临时路径)
WB_CHECKIN_REPORT=/tmp/test.md python check_in_v2.py --force --no-task --debug
# 查计划任务下次唤醒时间(沙箱内 schtasks 可能被拦,可直接读任务 XML)
schtasks /query /tn WorkBuddyCheckIn /fo LIST /v

日志轮转:超过 256 KB 自动归档为 workbuddy-check-in.log.1,不会无限增长。

注意事项

  • 运行时保持 WorkBuddy 窗口存在(前台/后台被遮都行,别最小化/关到托盘——
    脚本会自动恢复显示,但全程不激活窗口、不抢前台、不动鼠标,可放心在
    游戏/全屏场景后台静默运行;若窗口被其他应用完全遮挡、Chromium 不渲染 UIA 树,
    仍可能 FAIL)。
  • 点击过程中不要手动锁屏。
  • 日志是高信噪比台账(v14 契约,见上),正常每天 1–2 行;但要记住:
    日志只反映"跑到过什么",签到是否真的到账仍以 WorkBuddy 界面或用户确认为准。
    反过来说,某天日志完全空白本身就是异常,必须主动排查。
  • WorkBuddy 升级后若元素/文字变化:改 scripts/config.json 对应项即可(用户名、
    窗口标题、入口/领取按钮关键词、头像锚点偏移),无需改脚本代码。

需要实现细节时再读取:

  • references/checkin-reference.md

常见问题

5 问
答案由本站依据条目字段整理
WorkBuddy 自动签到怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_7c33246a/workbuddy-auto-checkin。安装方式为未标注。装完刷新技能列表或重开客户端。

WorkBuddy 自动签到支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

WorkBuddy 自动签到权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

WorkBuddy 自动签到收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

WorkBuddy 自动签到用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。