Repository navigation
Releases: jianghui1974/Quileg-HID
Release list
v0.9.70 — 坏轴四角量完再镜像,续校从 TL 不再必然失败
两个安装包
| 包 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.70-arm64.dmg |
Apple 芯片(M1–M4) | 725313bf76adbd8e30b05a095d86b83e5fc800154066a0720c044c49a248a1a7 |
Quileg-HID-0.9.70-intel.dmg |
Intel Mac(macOS 13–26) | eee3b39f89f58d3bc5dad81f065d3dc6a60e58f3e407f44771fba836a2127c1e |
一句话:坏轴先记账、四角量完再对角镜像 —— 「从 TL 继续」不会再因为顺序必然失败。
装法:⌘Q 完全退出旧版 → 双击 DMG → 拖进「应用程序」覆盖 → 从「应用程序」打开 →
手机控制中心重选「屏幕镜像 → Quileg」。
GPL-3.0:uxplay-master-source.tar.gz + uxplay-build.patch,说明见 uxplay-master-source.txt。
Quileg HID 0.9.70(Build 125)
2026-10-28 坏轴先记账、四角量完再镜像:「从 TL 继续」不会再必然失败
1. 为什么还要这一版
0.9.69 的「覆盖不足当场判」有个副作用:测量顺序是 BL → BR → TL → TR,
所以 TL 的坏轴出现时,TR 还没量,镜像源不存在 → 只能中止。
结果就是这台机器的 TL 角只要读不到,续校从 TL 开始必然再失败一次(22:32 那轮就是这样)。
2. 现在的做法
- 量完某一轴发现「全平 / 覆盖不足」→ 只记账(
_bad_axes),不中止; - 四角都量完后
_resolve_bad_axes()统一处理:这时对角一定已经量过 → 用对角镜像
(x 用1−f、y 同理),并记一条「TL x 轴读数没变化,用对角 TR 镜像兜底(验证会核)」; - 对角也没有可用轴 → 才报错(带跨度 + 下一步)。
所以 TL x 读不到时,这一版会用 TR x 镜像出一张可用的表,再由验证闸门判真伪;
最坏情况仍然是回滚,但不会再因为「顺序」白跑。
3. 回归
- App:639 passed(0.9.69 的 637 + 2:坏轴延迟处理后镜像 / 无镜像源时报错),
剩 1 条既有失败test_frame_freshness.ForceSystemZoneTest; - 延迟处理的可测性:
_resolve_bad_axes()抽成方法,用真实坏轴快照
[[20,0.1505],[1100,0.1505]]+ 好轴[[20,0.9],[1100,0.05]]断言镜像结果。
4. 已知限制(不变)
- 底角/顶角贴边(
y<0.03或y>0.99)时读数本来就不可靠:这版会镜像或当场说清楚,
但要真正量准,得在 pointer-tester 侧把 HUD 挪开(待做); - macOS 13.x 上采集卡(UVC)不可用,需 14+;Intel 上 OCR 走
.fast。
v0.9.69 — 轴覆盖不足当场判(和验证同一个 40% 阈值)
两个安装包
| 包 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.69-arm64.dmg |
Apple 芯片(M1–M4) | 128848274070596e3f41d234b7accf2b8b3aa1e9f435e10925ff4d5269818333 |
Quileg-HID-0.9.69-intel.dmg |
Intel Mac(macOS 13–26) | 7ef3652ebfabf33a3944248de1acb6b0502a47eba4a78552aa691931a216d8fa |
一句话:校准的「坏轴」判据和验证用同一个阈值(覆盖 40%),量完一轴就判,
不再等到 19 分钟后被拒。
装法:⌘Q 完全退出旧版 → 双击 DMG → 拖进「应用程序」覆盖 → 从「应用程序」打开 →
手机控制中心重选「屏幕镜像 → Quileg」。
GPL-3.0 履约:uxplay-master-source.tar.gz + uxplay-build.patch,说明见 uxplay-master-source.txt。
Quileg HID 0.9.69(Build 124)
2026-10-28 校准的「坏轴」判据和验证用同一个阈值:覆盖不足当场判,不再等到最后
1. 只覆盖一小段,也算这一轴不可用
现象(本机 22:14 那轮):BL y 只采到 3 档 —— 0.9385 / 0.9093 / 0.8727,跨度
0.07;其余 7 个轴都在 0.77–0.92。这张表写进去后,验证抽到 y≈0.5 的目标时
units_for 只能外推 → 指针飞到边 → 单点几百 px → 两轮不过 → 回滚(19 分钟)。
为什么 0.9.68 没拦住:那道「平轴」闸门判的是跨度 < 0.02(完全没动),
这张表跨了 0.07 —— 它动了,只是只动了一小段。而验证里早就有一条
MIN_AXIS_SPAN = 0.40 的覆盖率闸门。同一个问题两套标准,前面那道就形同虚设。
修法:
- 量完每个轴当场用
axis_covered()(阈值MIN_AXIS_SPAN = 0.40)判; - 不足 → 抛
FlatAxis(min_span=0.40)→ 先用对角镜像兜底 → 还不行就带数字报错:
「BL y 轴不可用(3 档,跨度 0.07)… 多半是指针在这个角读不到位置」; - 时间从 19 分钟缩到 3–5 分钟,而且不用等到验证。
2. 顺带(同一天早些时候,已在本版)
- 没有校准表时不再往视频上盖「还没有校准表(可选)」卡片(0.9.68,§2.36);
- 删
calib.json即失效,MCP 也会重载成空表(0.9.68,§2.37); - 「恢复初始设置」补上
calib.json.bak-*/.bad-*/calib.running。
3. 回归
- App:637 passed(0.9.68 的 634 + 3:覆盖不足判定 / 正常轴覆盖 / 文案),
剩 1 条既有失败test_frame_freshness.ForceSystemZoneTest的
'Dev' object has no attribute 'base'; - 用本机真实坏轴做样本:
[[30,0.9385],[60,0.9093],[100,0.8727]]必须判「未覆盖」。
4. 已知限制(不变)
- macOS 13.x 上采集卡(UVC)不可用,需 14+;AirPlay 不受影响;
- Intel 上 OCR 走
.fast(degraded=true); - 底角停车点如果贴在屏幕最底边(
y>0.99),那一带的读数本来就不可靠 ——
这版会当场判坏,但要让底角真正量得准,还得在 pointer-tester 侧把 HUD 挪开(待做)。
v0.9.68 — 校准平轴 20 秒内失败、没有表不再盖卡片、删表即时失效
两个安装包
| 包 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.68-arm64.dmg |
Apple 芯片(M1–M4) | b8f0ed626289a495ef4f731848fc1e973eb29631db0375812a67323bf2a81149 |
Quileg-HID-0.9.68-intel.dmg |
Intel Mac(macOS 13–26) | 7080207e307fbe673d49792a8957a52e7fe02b482547fb7c225d9b68b48bca6e |
这一版是「校准挫败感」的收尾:平轴 20 秒内失败(不再拖 19 分钟)、没有表时不再有卡片和视频抢画面、
删表/恢复初始设置立刻生效。
装法:先 ⌘Q 完全退出旧版 → 双击 DMG → 把「Quileg HID」拖进「应用程序」覆盖 →
从「应用程序」打开 → 手机控制中心重选「屏幕镜像 → Quileg」。
GPL-3.0 履约:uxplay-master-source.tar.gz(上游快照)+ uxplay-build.patch,说明见 uxplay-master-source.txt。
Quileg HID 0.9.68(Build 123)
2026-10-28 校准不再「19 分钟才失败」+ 没有表时不再有卡片抢画面 + 重置/删表即时生效
1. 没有校准表时,视频上不再有卡片和它「互相盖」
现象(用户现场):删掉校准表之后,视频上每 1/8 秒出现又消失一张卡片
「还没有校准表(可选)」+「校准向导」按钮,看起来像弹窗在跟视频抢前台。
根因:_update_empty() 把「没有表」当成「空画面」盖上卡片,而 _on_frame()
每来一帧又 clear_empty();AirPlay 8 fps,于是 125 ms 闪一次。
这是老代码 —— 以前新装都带种子表(calibrated=true),所以从没触发;0.9.67 起
新装默认没有表,才把它翻出来(PITFALLS §2.36)。
修法:没有表不再算「空」。真正盖卡片的只剩「服务端没响应」「没有投屏」;
没有表的提示只留在读数条的 定位 视觉(未校准) 和检查器里。
2. 校准:平轴 20 秒内失败,不再拖到验证(19 分钟)
上一轮用户实测:TL 角探针和帧差都读不到 → 停车点用圆角几何模型估到 (0.051, 0.023)
→ 这个角的 x 轴 12 档读数全是 75 px(0.1505)→ 表塌成两个相同的点 →
验证 266/360 px 两轮都不过 → 回滚,前后 19 分钟。
修法:
- 平轴当场判定:任一轴两个点以上、跨度 < 0.02 → 抛
FlatAxis; - 对角镜像兜底:x 用对角 1−f、y 同理再交给验证核;对角也没有可用表就立刻报错;
- 停车点来自几何模型时先验证这个角:往屏幕中心挪 80 单位重读两次,
读不到就 20 秒内中止 并直说「这一个角硬测出来的表不能用:把 Pointer Tester
的 HUD 挪开、或换一个静态页后重跑」。
3. 校准期间自动关掉「OCR 实时识别」
实测那轮里,实时 OCR(每 1.5 s 一次 ocr_jpeg)和探针抢同一条 Apple Vision 管线,
最难的角更容易读不到。现在开始校准 / 快速自检时自动关掉,并在日志里说明原因。
4. 删表 = 立刻失效(含 MCP 侧)
calib_stale()/refresh_calibration()现在把「文件没了」也当变化:
以前只看 mtime,删文件后 mtime=0 不触发重载,于是 GUI 走视觉闭环、
MCP 还拿着内存里的旧表算位置(exists:false但profiles还列着两张表);- 「恢复初始设置」的匹配补上
calib*.json.*(calib.json.bak-20261024-105105、
calib.json.bad-1136这类备份)与calib.running。
5. 回归
- App:634 passed(0.9.67 的 618 + 本轮 16:平轴/镜像/角可读性 9、空状态 4、
删表失效 1、重置范围 2),剩 1 条既有失败test_frame_freshness.ForceSystemZoneTest
的'Dev' object has no attribute 'base'(HEAD 上同样失败); - 用真实失败快照做回归样本:
[[20, 0.1505], [1100, 0.1505]]必须判平。
6. 已知限制(不变)
- macOS 13.x 上采集卡(UVC)不可用,需 14+;AirPlay 不受影响;
- Intel 上 OCR 走
.fast(degraded=true); - 视觉闭环本来就比表慢:小图标、密集列表、拖拽/长按建议校准一次。
v0.9.67 — 新装不再带种子表、快速自检、恢复初始设置
两个安装包
| 包 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.67-arm64.dmg |
Apple 芯片(M1–M4) | 98cfc8a3d7eb759348176a818e40e83a1008729f0e5d3f263e3e6a5a73e321e3 |
Quileg-HID-0.9.67-intel.dmg |
Intel Mac(macOS 13–26) | 95064c57120e438b1011b435791c36370579febf97b8a9bebfc7f847a6408b7d |
第一次用:装好直接就能用 —— 新版本不再预装一份「别人手机上量的」校准表;
没有表时走视觉闭环(精度 10–40 px、每次动作多 2–6 s),大按钮、列表、开关都够用。
想要更准(小图标、密集列表、拖拽/长按)再花 15–30 分钟校准;装好旧版本的也可以用
校准向导里的「快速自检(10 秒)」判断现有表值不值得用。
装法:先 ⌘Q 完全退出旧版 → 双击 DMG → 把「Quileg HID」拖进「应用程序」覆盖 →
从「应用程序」打开 → 去手机控制中心重选「屏幕镜像 → Quileg」。
两个包不通用,装错会提示「需要 Apple 芯片」;包内 VERSION.txt 的 Arch: 行可核对。
GPL-3.0 履约:uxplay-master-source.tar.gz(上游快照)+ uxplay-build.patch(对应源码 = 上游 + 该 patch),说明见 uxplay-master-source.txt。
Quileg HID 0.9.67(Build 122)
2026-10-28 新用户先跑起来:不再安装「别人家的」种子校准表 + 快速自检 + 恢复初始设置
1. 新装不再带校准表(这是本轮最重要的一条)
现象(复盘,来自用户提问):新用户第一次点东西就偏几十 px,status 却报
calibrated=true、positioning=table,日志里一点异常都没有。用户描述是「点了没反应」。
根因:数据目录没有 calib.json 时,程序会把包里那份 control/calib.json
(在开发机的 iPhone 上量的)复制过去。AirPlay 帧恒为 500×1080,键
airplay:500x1080 对任何手机都命中 —— 这份表必然被启用,而它本来只适合那一台手机。
对照:没有表时走视觉闭环(10–40 px、每动作多 2–6 s),读不到指针会直接报错,
不会静默点偏。「装了别人的表」比「没表」更糟:它把诚实降级变成了不可见的误差。
修法:
- 不再自动安装种子表(文件改名
calib.seed.json,只作参考); - 数据目录没有表就是没表:
positioning=visual,大按钮、列表、开关都照常能用; load_calib()把「文件不存在」当成空表而不是错误(「恢复初始设置」删表后也安全)。
2. 试用表 + 快速自检(10 秒)
- 向导成功写入
verified: true;没有这个标记的表仍可用,但界面标「定位 试用表」,
status.table.verified也给 AI 看; - 校准向导里新增 「快速自检(10 秒)」:抽 4 个点,中位 > 40 px 就写
table_disabled+disabled_reason,positioning()从此走视觉闭环; - 表不删:重新校准成功后标记自动清掉;
status里多一个table_disabled_reason,AI 不用猜「为什么现在慢了几秒」。
3. 新手引导与状态显示
- 引导第 8 步主按钮改成 「先这样用(稍后校准)」,次按钮才是「现在校准(15–30 分钟)」,
文案直接说清楚「没有表也能操作,精度 10–40 px、每次多 2–6 s」; - 读数条右侧常显 定位模式:
定位 表/定位 试用表(建议自检)/定位 视觉(未校准),
用户和 AI 都能看出「为什么这次精度不一样」。
4. 恢复初始设置(设置 → 危险区)
- 可勾选 校准表 / 日志 / 设置,确认后真删;
- 板子的 Wi-Fi、NVS、固件一律不动(那在硬件里,误删要重新配网);
- 清完提示
⌘Q完全退出再打开(外观/缩放等设置需重开才生效)。
5. 回归
- App:618 passed(0.9.66 的 602 + 本轮 16:恢复范围 6 / 无种子与试用表 6 / 自检 4),
剩 1 条既有失败test_frame_freshness.ForceSystemZoneTest的
'Dev' object has no attribute 'base'(HEAD 上同样失败); - 真机 Tk 冒烟:定位标签配色、校准向导「快速自检」按钮的显隐与结果文案、
恢复对话框三个勾选项默认全选 —— 均通过; - 老测试里 4 处「读种子表」的 fixture 改成
calib.seed.json;「默认路径会复制种子」
那条断言反过来(现在断言不复制)。
6. 已知限制(不变)
- macOS 13.x 上采集卡(UVC)不可用,需 14+;AirPlay 不受影响;
- Intel 上 OCR 走
.fast(degraded=true),准确率略低; - 视觉闭环(没表)本来就比表慢:小图标、密集列表、拖拽/长按建议还是校准一次。
v0.9.66 — 取消校准立刻停、OCR 开关、macOS 13 上的 UVC 退避
两个安装包
| 包 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.66-arm64.dmg |
Apple 芯片(M1–M4) | 58b9f41574c07b61c013e71d077334720282017fbdf7eabf5507eeaabb03874f |
Quileg-HID-0.9.66-intel.dmg |
Intel Mac(macOS 13–26) | 7ad5c9b25f725236db8ce16a68a32cca79aa27d9f3d7de6fedb875692dbdc027 |
装法:先 ⌘Q 完全退出旧版 → 双击 DMG → 把「Quileg HID」拖进「应用程序」覆盖 →
从「应用程序」打开(别在 DMG 窗口里直接双击运行,那会进 AppTranslocation 临时目录)→
去手机控制中心重选「屏幕镜像 → Quileg」。
两个包不通用,装错会提示「需要 Apple 芯片」;包内 VERSION.txt 的 Arch: 行可核对。
GPL-3.0 履约:uxplay-master-source.tar.gz(上游快照)+ uxplay-build.patch(对应源码 = 上游 + 该 patch),说明见 uxplay-master-source.txt。
Quileg HID 0.9.66(Build 121)
2026-10-28 校准「取消」立刻生效 + OCR 改成开关 + macOS 13 上的 UVC 不再每秒重启
1. 取消校准:从「等完当前步骤」到「立刻停」
现象(2026-10-28 用户现场):点「取消校准」,界面写「正在取消…(当前步骤结束后停止)」,
实际要等很久 —— 有时像没反应。
根因:只有 progress() 回调里检查取消信号。而一档约 17 s;链路宽限(板子抖了之后
停下来等它恢复,最长 3 分钟)里连 progress() 都不调,所以这段时间点取消完全没有效果。
修法:
- 所有等待改走
_sleep():每 0.1 s 查一次取消信号,_retry的两层(6 次快速重试 /
3 分钟宽限)都能被打断;实测从点取消到抛出 18 ms(宽限窗口是 120 s 的那次对照)。 - 取消单独分成
CancelledCalibration:不是故障 —— 不生成Failure、不弹「哪里坏了」、
日志里不再留一条假的「中断:…」;只把内存里的半成品表回滚。 - 四角已测完、正在验证时取消:保留刚量好的整张表(以前会走进通用回滚,把文件还原成
旧表,等于 20 分钟白跑)。 - 文案:「正在取消…(当前步骤结束后停止)」→「正在取消…」。
2. OCR 改成开关:开着自动刷新,再点关闭
现象:点完工具条上的 OCR,识别框留在画面上,只有一个很小的角标能清,看起来「关不掉」;
想看新画面还得再点一次。
修法:
- 工具条 OCR 与右上角角标是同一个开关:开着时约 1.5 s 重识别一次,再点一下关闭并清框。
- 只在换帧时重识别(画面静止时 AirPlay 本来就不发帧,重复识别纯浪费);上一轮没回来
时这一轮跳过,不会堆线程;识别到的块数没变就不刷日志。 - 实时模式下框不再被标成「可能已过期」;这一帧 0 块也保留角标(它是关闭入口之一)。
- 自动收:窗口隐藏(红叉)时关闭、切服务端时关闭、OCR 报错时关闭并提示一次
(而不是每 1.5 s 弹一次)。
3. macOS 13:UVC 助手不再每秒崩溃重启
现象(同一客户机,macOS 13.7.8):app.log 每秒一条
UVC capture exited (code -6), restarting,把日志撑到 10 MB,还白烧 CPU —— 即使根本没插采集卡。
根因:0.9.65 的 uvc-frame 用了 macOS 14 的 AVCaptureDevice.DeviceType.external。
二进制里 _AVCaptureDeviceTypeExternal 是强引用,13.x 的 AVFoundation 没有这个符号,
进程一启动就被 dyld 打死(退出码 -6)。(这跟 §0.9.65 修的 Swift 运行时符号是两回事:
那个是打包目标写错,这个是真实的系统下限。)
修法:
uvc_supported():macOS < 14 时根本不拉子进程,只留一条 WARNING,并把
「UVC 采集需要 macOS 14+(这台是 13.7);AirPlay 投屏不受影响」写进/api/status;- 兜底退避:任何「启动即崩」(退出码为负且活了不到 5 s,或 stderr 里出现
dyld/
symbol not found)走 5 → 10 → 20 … 最多 300 s 的退避,日志限流(首次 + 每 5 分钟); - 正常跑满 30 s 之后再崩,重新从 5 s 开始计数;
no uvc capture device(没插卡)仍安静地
每 30 s 重试,camera access denied仍退避 60 s。
影响面:只在 macOS 13.x 上(14+ 完全不变)。要在 13.x 上用采集卡只能升级系统 —— 那是
Apple 的 API 下限,不是包的问题。
4. 回归
- App:602 passed(0.9.65 的 585 + 本轮 17:取消 7 + OCR 开关 10),
剩 1 条既有失败test_frame_freshness.ForceSystemZoneTest的
'Dev' object has no attribute 'base'(HEAD 上同样失败); - Server:新增
tests/test_uvc_guard.py6 条(版本闸门 / 退避曲线 / 不拉进程 / 启动即崩退避); - 真机 Tk 冒烟:OCR 开关点亮 → 画 2 个框 → 再点 → 框清零、按钮熄灭;实时 + 0 块仍可关。
5. 已知限制(不变)
- macOS 13.x 上采集卡(UVC)不可用,需 14+;AirPlay 投屏不受影响;
- Intel 上 OCR 走
.fast(degraded=true),准确率略低,属已知限制; - 校准要求「命令回执」在几百毫秒内;回执 1.2 s 的链路先修 Wi-Fi。
v0.9.65 — 修旧 macOS 上 OCR/UVC 工具启动失败(紧急)
两个安装包
| 包 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.65-arm64.dmg |
Apple 芯片(M1–M4) | a6a2e29553e3fec4f8bcf0f0b664cf54eb6c1ed9130a26c7dff671ca0affc4de |
Quileg-HID-0.9.65-intel.dmg |
Intel Mac(macOS 13–26) | 72cb5c540af627e99a02d5cd328d2f9baaa1514600c6cf92d2e06696de7787a5 |
这是紧急修复:0.9.45–0.9.64 的包在 macOS 26 之前的系统上,ocr-text / uvc-frame 会因为引用新版 Swift 运行时符号被 dyld 拒绝启动 —— OCR 与 UVC 直接不可用(校准表现成「每一档都读不到指针」)。装 0.9.65 即可。
两个包不通用,装错会提示「需要 Apple 芯片」;包内 VERSION.txt 的 Arch: 行可核对。
GPL-3.0 履约:uxplay-master-source.tar.gz(上游快照)+ uxplay-build.patch(对应源码 = 上游 + 该 patch),说明见 uxplay-master-source.txt。
Quileg HID 0.9.65(Build 120)
2026-10-28 紧急:旧 macOS 上 OCR / UVC 工具起不来(打包目标写错)+ 校准三道防呆
1. 为什么急:客户在 Intel Mac 上校准,每一档都「读不到指针」
客户(Intel Mac,macOS < 26)的校准日志从第一档开始全灭,app.log 里刷了 1.7 万行同一句:
dyld[34569]: Symbol not found: _$ss20__StaticArrayStorageCN
Referenced from: .../control/bin/uvc-frame
Expected in: /usr/lib/swift/libswiftCore.dylib
根因:build_release.sh 用宿主 macOS 27 编译 Swift 工具,再用 lower_app_minos.py
把 minos 改成 13.0 —— 那是假的最低系统。dyld 只认符号:__StaticArrayStorage 是
Swift 6.2 运行时的符号,旧系统的 libswiftCore 里没有,于是 ocr-text / uvc-frame
一启动就被 dyld 拒绝。
后果:ocr-text 起不来 → ocr_barcodes() 返回空、ocr_jpeg() 抛错 → probe.read_state()
静默返回 None → 校准每一档都读不到指针。看起来像「链路太慢」,实际是我们的工具没跑起来。
(同一张 calib-fail-*.jpg 在开发机上一次就解出 P1,67.85,823.48,2049,390,844,帧完全正常。)
修法:
- 按真实最低系统编译:
ocr/textsize→macos13.0,uvc→macos14.0
(uvc 用了 macOS 14 的externalAPI);六个产物实测__StaticArrayStorage引用数 0; - 构建期闸门:
nm -u里再出现这个符号就直接中止构建,不再靠人眼; ocr.py:助手起不来/报错时留一行 WARNING(每进程一次)——这次就是「静默」把排查成本放大的。
影响面:0.9.45–0.9.64 的所有包在 macOS 26 之前的系统上都有这个问题(arm64 / Intel 都一样),
只是新系统上符号存在,所以一直被掩盖。升级到 0.9.65 即可。
2. 校准:延迟太高直接拒绝(不再跑 20 分钟产出坏表)
投屏延迟 2813 ms 的链路上,每一档读到的都是移动前的画面 —— 探针给的是真值,
但是两秒前的真值。这种表写进去,点击会系统性偏短,比没有表更危险。
现在测完延迟立刻判:中位 > 1200 ms 就中止,并给出两个数字 + 修链路的动作
(板子靠近 AP / 换 2.4 GHz 信道 / Mac 插网线 / 暂停同步下载)。正常量级是 150–530 ms。
3. 校准:「继续校准(从 TL 开始)」但实际从 BL 开始
实际量角顺序一直是 BL、BR、TL、TR(底角先测,顶角靠底角的 y 表反推上行距离),
但「待测清单」按 TL, TR, BL, BR 排,于是按钮写 TL、跑起来却是 BL。
新增 MEASURE_ORDER,两者统一。
4. 校准:进度停住时不再吹牛
日志里 约剩 2 分钟 → 5 → 8 → 11 → 13 → 16 分钟,而那一轮 30 秒后就中断了 ——
进度比例不动时按 elapsed/frac 外推只会越算越大。现在:进度停止 120 s 就改成
「已 X 分钟没有进展」;另外 done 为空时不再说「已测好的部分已保留」(其实什么都没留下)。
5. 回归
- 新增测试:延迟闸门(3)、续校顺序(2)、进度停摆口径(4)、助手失败留痕(1);
- 全套 572 → 585 passed(
test_frame_freshness.ForceSystemZoneTest的 1 条
'Dev' object has no attribute 'base'在 HEAD 上同样失败,属既有问题); - 六个 Swift 产物逐个校验:
__StaticArrayStorage= 0,minos 13.0/14.0,两个架构都能跑
(arm64accurate21 blocks;x86_64 Rosettafast / degraded)。
6. 已知限制(不变)
- 校准要求「命令回执」在几百毫秒内;回执 1.2 s 的链路先修 Wi-Fi;
- OCR helper 内部没有看门狗:
.accurate卡住靠 MCP 的 30 s 超时兜底; type_text第一个空格偶尔被 iOS 自动更正吞掉(重打一次即可);- intel 包仍未在真 Intel Mac 上做完整验收(本轮由客户现场暴露并回归了 OCR 路径)。
v0.9.64 — 串口改名自动恢复、校准不再卡在最小档位
两个安装包
| 包 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.64-arm64.dmg |
Apple 芯片(M1–M4) | 59778440e0ab864fb2ebcc837c4e701bf2e5a1b62a65075cb20c32855281d9e6 |
Quileg-HID-0.9.64-intel.dmg |
Intel Mac(macOS 13–26) | c859d53379334c0ac746a1464fae0b48d4f7e6e10daf491fc619d6784f911a0d |
两个包不通用,装错会提示「需要 Apple 芯片」;包内 VERSION.txt 的 Arch: 行可核对。
GPL-3.0 履约:uxplay-master-source.tar.gz(上游快照)+ uxplay-build.patch(对应源码 = 上游 + 该 patch),说明见 uxplay-master-source.txt。
Quileg HID 0.9.64(Build 119)
2026-10-28 两个客户现场问题的修复:串口改名后写 Wi-Fi 不再报错、校准不再卡在最小档位
1. 写 Wi-Fi 报 [Errno 2] could not open port …:端口改名了
客户现场:设备初始化第 4 步选了 /dev/cu.usbmodem1234561,第 5 步「写入并应用」直接失败;
退回第 4 步点「刷新」出现了一个新端口,重选后写入正常。
根因:macOS 的串口名 = usbmodem + USB 描述符里的序列号 + 接口号。同一块板在不同固件/模式下
串号会变(Espressif 占位串号 123456 ↔ MAC 派生如 84C7BB70AF64),旧路径就不存在了。
而向导只在打开时枚举一次端口,第 5 步拿旧名字 open() → ENOENT,还把 Python 原始异常
直接显示给用户。
现在(provision.resolve_port()):
| 情况 | 行为 |
|---|---|
| 旧端口还在 | 原样使用 |
| 旧端口没了、只剩一个候选 | 自动改用,并提示「端口已变化(A → B)」 |
| 多个候选 | 不猜,报错列出候选,让用户回第 4 步重选 |
| 一个都没有 | 「找不到板子的串口:插好数据线、换 USB 口、点刷新重选」 |
向导进第 5 步会刷新端口列表,写入前再复核一次;Wi-Fi 对话框走同一套逻辑;
_open() 把 FileNotFoundError / SerialException 统一转成能读懂的 PortError。
2. 校准:中断原因被吞成 <built-in method title …>
客户日志里出现过:
中断:<built-in method title of str object at 0x10b370fb0>
预检拦截那四句(校准已经在跑 / 服务端未响应 / 没有投屏画面 / 队列已满)传的是字符串,
而 fail() 用 getattr(failure, "title") 取标题 —— 对 str 拿到的是 str.title 这个
绑定方法(真值),于是真正的原因(哪条预检没过)被顶掉了。
现在 failure_parts() 同时接受字符串与 calibration.Failure,四种拦截会原样显示原因。
3. 校准:小位移读不到不再判整轴废掉
同一份日志:BL x=20 读不到 → 跳过;BL x=40 再读不到 → 旧规则「连续两档」直接判这一轴废掉。
于是每一轮都死在同一格,客户连点 8 次「继续校准」也推进不了。
现在按档位大小分级(MissTracker):
- 小档位(<150 单位):最多连着跳 4 档,不判废(20 单位 ≈ 13 px,本来就在帧差噪声里);
- 中/大档位(≥150):连着 2 次读不到才放弃这一轴;
- 任何一档读到了,计数清零。
顺带把文案改准:已经退回帧差还失败时,标题是「指针读不到(探针和帧差都没读到)」,
并直接提示「链路延迟超过 1 秒先修 Wi-Fi」,不再让用户去折腾一个已经失效的探针。
4. 校准:剩余时间不再反向增长
日志里 约剩 3 分钟 → 6 → 10 分钟。progress() 用 elapsed / frac 估剩余时间,
而 frac 在重试/换角时会回落 → 估算爆炸。现在只用历史最大比例,并给上限。
5. 文档
PITFALLS.md新增 §2.29(端口改名)、§2.30(小档位读不到);AI_GUIDE.md/PITFALLS.md里补了 Pointer Tester 的 TestFlight 外部测试入口
(iOS 17+,不联网、只显示坐标),AI 建议用探针时能直接把安装入口给用户。
6. 回归
- 新增
test_provision_port.py(8 条)、test_calib_failure_text.py(7 条)、
test_calib_miss_tolerance.py(9 条); - 全套 548 → 572 passed(
test_frame_freshness.ForceSystemZoneTest的 1 条
'Dev' object has no attribute 'base'在 HEAD 上同样失败,属既有问题)。
7. 已知限制(不变)
- 校准遇到「指令回执 >300 ms」时仍然很慢;回执 1.2 秒的链路校准没有意义,先修 Wi-Fi;
- OCR helper 内部没有看门狗:
.accurate卡住靠 MCP 的 30 s 超时兜底; type_text第一个空格偶尔被 iOS 自动更正吞掉(重打一次即可);- intel 包仍未在真 Intel Mac 上验收(本轮只在 Rosetta 下验了架构、签名、包内 helper)。
v0.9.63 — OCR 降级不再静默
两个安装包
| 包 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.63-arm64.dmg |
Apple 芯片(M1–M4) | d0b7c135d33c1fec82397522b7a601bd5eab6785b3bde25c3f5feacbfc972e12 |
Quileg-HID-0.9.63-intel.dmg |
Intel Mac(macOS 13–26) | 2732441372074069cb8eb943588c837710b9942a2b1069a9a1634b1f9427162b |
两个包不通用,装错会提示「需要 Apple 芯片」;包内 VERSION.txt 的 Arch: 行可核对。
GPL-3.0 履约:uxplay-master-source.tar.gz(上游快照)+ uxplay-build.patch(对应源码 = 上游 + 该 patch),说明见 uxplay-master-source.txt。
Quileg HID 0.9.63(Build 118)
2026-10-27 OCR 降级不再静默:结果里带
degraded,MCP / GUI 都会说出来
1. 问题:.accurate 悄悄退 .fast,调用方只看到「字变少了」
用户报「包内 ocr-text 每次调用都打 ocr: accurate 不可用,已降级为 fast(unknownError),
同一张图包内 7 个 block / 开发版 20 个,中文全是乱码」。
定位(PITFALLS §2.28):不是签名、不是 hardened runtime、不是打包。
.accurate 走 ANE(TextRecognition → e5rt),需要 mach-lookup,且依赖
~/Library/Caches/vision_arm64 里编译好的模型;被沙箱掐掉或缓存不可用时,Vision 抛一个
没有信息量的 Foundation._GenericObjCError 0,.fast 仍然可用 —— 于是 helper 静默降级。
包内那份二进制在普通终端 3/3 正常(accurate / 21 blocks),改名/重新签名等 5 种组合也全部正常;只有换到受限进程才复现。
真正的问题是:降级对上层不可见。MCP 只看到 block 变少,AI 会以为「图里没字」,
于是换目标、重复点、把「列表锚点认不出」归因成页面问题。
2. helper:状态跟着结果一起回
control/ocr.swift 的输出从 {blocks, barcodes} 扩成:
{"blocks": [...], "barcodes": [...],
"engine": "accurate|fast", "degraded": false, "degraded_reason": "…"}.accurate失败先原地重试一次(ANE 偶尔起不来),两次都失败才降级;- 降级时 stderr 除了原来那句人话,再打一行机器可读的
OCR_DEGRADED engine=fast reason=…; - 错误描述补上
domain/code(Vision 的localizedDescription常是空壳)。
3. 三层都要看得见
| 层 | 行为 |
|---|---|
ocr_jpeg() |
结果带 engine / degraded / degraded_reason;只 WARNING 一次(每帧刷会把 app-ui.log 淹掉);老 helper 只在 stderr 说一句时也照样识别成降级 |
MCP ocr() |
摘要顶部 ⚠️ OCR 引擎已降级为 .fast(…),结构化返回里也有 degraded |
MCP click_text |
找不到目标且引擎降级时,提示「漏认可能是引擎问题,不是目标不存在」 |
| GUI OCR 面板 | 日志里留一行降级原因,不再只躺在 stderr 里 |
| 超时 | TimeoutExpired 转成一句能转述的原因(.accurate 卡在模型编译时常见),不再裸抛 |
4. 回归
- 新增
app/tests/test_ocr_degraded.py(6 条:accurate / degraded / 老格式裸数组 /
老 stderr 提示 / 只告警一次 / 超时文案); - 全套 542 → 548 passed(其中 6 条为本版新增;
test_frame_freshness.ForceSystemZoneTest
的 1 条'Dev' object has no attribute 'base'在 HEAD 上同样失败,属既有问题,与本版无关); - 真机 A/B(同一份包内二进制、同一帧):普通终端 3/3
21 blocks(.accurate);
sandbox-exec … (deny mach-lookup)下14 blocks+ 那句已降级为 fast(nilError)。
codesign --verify --deep --strict通过 —— 包体本身是完整的。
5. 已知限制(不变)
- helper 内部没有看门狗:
.accurate卡住时靠 MCP 的 30 s 子进程超时兜底;
GUI 那条线程会一直等(界面不卡,但结果不回来)。 type_text第一个空格偶尔被 iOS 自动更正吞掉(重打一次即可);- intel 包尚未在真 Intel Mac 上验收。
v0.9.62 — 参数错误说人话了
Quileg HID 0.9.62(Build 117)
2026-10-27 参数错误说人话了 + 操作手册补「防误触 / 开放」两种模式
1. 参数不合法 → 结构化错误(不再是一句「Error executing tool xxx」)
以前参数错了(坐标越界、mode 拼错、button 不认识、text 为空)是 raise ValueError,
宿主把它压成一句 Error executing tool click,具体原因全丢,AI 只能瞎猜。
现在这些入口统一返回:
{"ok": false, "code": "invalid_args", "reason": "mode 只能是 guard(防误触)或 open(开放),收到 'careful'", ...}覆盖 click / move / type_text / ocr_timeline 的参数检查;不会碰设备(测试里断言了
click_verified / move_to 没被调用)。
2. AI_GUIDE.md 补 §1.1a:两种控制区模式
写清判断顺序:先 guard(默认)→ 看 clamped / effective 与截图 → 确实被钳住再
mode="open" 重试一次 → 仍没反应多半命中程序坞(看 dock_visible),别连点。
同时更新了文末维护记录。
3. 回归
- 542 passed(新增 7 条参数错误契约;原「越界必须 raise」的两条改成断言结构化错误)。
4. 已知限制(不变)
type_text第一个空格偶尔被 iOS 自动更正吞掉(重打一次即可);- intel 包尚未在真 Intel Mac 上验收。
资产
| 文件 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.62-arm64.dmg |
Apple 芯片(M1–M4,macOS 13+) | fb030f2ce6120085bf602546c807a38267e8a2a94dfeadb1375471100a77d44b |
Quileg-HID-0.9.62-intel.dmg |
Intel Mac(macOS 13–26) | a2731b6c754741be987d735b8b50bc80b33180f9209088be3c2d272b5129d62a |
两个包不通用;包内 VERSION.txt 的 Arch: 行可核对;下载后可用同 Release 的
.sha256 校验。GPL 履约见 uxplay-master-source.tar.gz + uxplay-build.patch。
v0.9.61 — 防误触 / 开放 两种控制区模式
Quileg HID 0.9.61(Build 116)
2026-10-27 两种控制区模式:防误触(默认)/ 开放(自担风险)
系统手势区(iPad 底部程序坞带 ~11%、顶部安全边 2%)以前是硬钳位——AI 想点也点不进去。
现在改成 AI 自己选:
| 模式 | 行为 | 用在哪 |
|---|---|---|
mode="guard"(默认,防误触) |
避开程序坞带与顶部安全边;目标被钳住时返回 clamped / effective,摘要提醒 |
日常点击,防止误触程序坞/主屏条/通知中心 |
mode="open"(开放) |
不钳位,底部最多到 98.5%;返回值标 forced,摘要写「后果自负」 |
AI 明确要进这些区域(例如 App 的控件确实压在最底部) |
- 两个名字都收:
mode="open"是新口径,force=True是它的旧写法; - 传了
mode以mode为准;都不传就是防误触;非法取值直接报错(列出可选值); status里多了一块zones,AI 一眼能看到「默认防误触、需要时可切开放」;- 开放模式下,底部停车点会按 y 表最后一段斜率往下放(
lift_shift),不是靠外推硬凑。
实测(iPad 1554×1080,move(0.5, 0.97)):
| 模式 | 指令落点 | 实测指针 | 返回值 |
|---|---|---|---|
| guard | 0.8927(钳到停车点) | 0.874 | clamped=true |
| open | 0.970 | 0.955 | forced=true、lift_shift=91.8 |
程序坞信号
dock_visible 改成「归位前 vs 归位后」比底边那一条(y>0.86),只报「这一条动过」,
不再猜「现在是开还是关」——开放模式把指针停在程序坞带里时也不会漏报。
回归
- 534 passed(新增 9 条:模式归一/别名/优先级/非法值/接线、status 的 zones 说明)。
已知限制
- 开放模式下点了没反应,多半是命中了程序坞或主屏条——看
dock_visible与截图再决定; - 顶部 2% 在 open 模式下也放开了,可能拉下通知/控制中心(按 Esc 收起)。
资产
| 文件 | 适用机器 | SHA-256 |
|---|---|---|
Quileg-HID-0.9.61-arm64.dmg |
Apple 芯片(M1–M4,macOS 13+) | a1c36018bcc4130967d2e5c6377e28c62fb155a71e069a4d762cdde66c0b1319 |
Quileg-HID-0.9.61-intel.dmg |
Intel Mac(macOS 13–26) | 99eda01d571d2411caf65ec0f15bf1f8e38f81e1e57ef960ec6236a7d128c397 |
两个包不通用;包内 VERSION.txt 的 Arch: 行可核对;下载后可用同 Release 的
.sha256 校验。GPL 履约见 uxplay-master-source.tar.gz + uxplay-build.patch。