Repository navigation
v2.4.1 —— 输入路径的三处静默故障
v2.4.1 —— 输入路径的三处静默故障
这一版没有新功能。它修的是**"读得到、打不进"**这一类问题:ui.get_tree 明明给出了
一个 id,ui.act 却告诉你"找不到这个元素",或者更糟 —— 动作返回成功,其实什么都没发生。
来源是一次三站点联调(Notion / Miro / Figma)。三个站点各有各的形态,而 Notion 暴露了
输入链路上三个互不相关的缺陷,每一个都把错误推给下一个。
1. 句柄来自元素原生 id,查找却只认 data-ai-id
抽取器在没有 data-ai-id 时用元素自己的 id 当句柄(existingAiId || nativeId)。
而 data-ai-id 只是页面里的一个普通属性 —— React 类应用重渲染那个子树时会把它一起抹掉,
元素本身还在。
实测(Notion 空段落):id=":r6:",data-ai-id 刚写就被抹空。于是 ui.get_tree 报
:r6:,ui.act 报 Target not found for ref: :r6:。
修法:属性查不到时按 getElementById 兜底,放在"穿透 shadow 的同一递归"里
(ShadowRoot 也有这个方法)。它不会把"不存在"变成"乱命中" —— 有阴性对照钉住。
2. focus() 不等于"可输入"
contenteditable 调 focus() 之后 document.activeElement 确实等于它 ——
所以"焦点坐上没有"这个判据看不出任何问题 —— 但 Notion 的块编辑器没进入编辑态,
随后所有受信按键全部落空,校验读到空,报 Input not verified。
真人点一下之后,activeElement 会交给编辑器自己的容器,按键才生效。
修法:contenteditable 一律先来一次真实指针点击。input/textarea 不加这一步 ——
原生控件 focus 就够,多点一下反而会把光标挪到中段,破坏 type 的 at:'end' 语义。
3. 校验读错对象 → 假阴性
清空 Notion 的空段落之后,它把焦点交还给页面(activeElement 变成 BODY),
校验读到的是整页文本,于是明明成功却报失败。
这个方向最危险:agent 看到失败会重试,对 type 就是写入两份重复内容。
修法:失败时再按"解析出来的那个可编辑元素"复核一次,命中就如实给成功并标
verified_by: 'target-element'。它不掩盖真错位 —— 文字若落进别的输入框,
目标元素里就没有它。
顺带修掉的(同一轮)
- GPU 画布上
canvas_changed:false是假阴性。Figma 的可见画布是 WebGPU,
DOM 里 2D 画布 0 张,而绘制钩子照样记到帧 —— 那些来自页面自己建的离屏 2D 画布。
一次真实的"宽度 100→200"改动,指纹一动不动,回执却说"证明没变"。
现在钩子自述g=1,上层把canvas_changed/canvas_idle一律降级成null(不可判)。
null意味着"无法判断",不是"什么都没发生" —— 这句话现在也写进了
ui.capabilities的说明里。 data-ai-id优先级:元素已有data-ai-id时必须优先沿用,不能被元素自己的id
改写。两条路径(AX 与 DOM 抽取)轮流改写同一个属性时,各自报出的 ref 都会被对方作废。
验证
- 单测 1128 / 81 文件
- e2e 23 套件 789 项全绿(richtext 117、readcov 99、capabilities 54、canvas 41…)
- 真站点:Notion 写入→回读→还原;Miro
create → get → sync → remove;
Figma 属性写入 → Mirror DOM 自述 "Dimensions 150 100" → 还原
全部写入都是可逆的,且已还原到原状。